package org.djutils.data;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.djutils.data.csv.CSVData;
import org.djutils.data.serialization.TextSerializationException;
import org.junit.Test;
/**
 * TestCSVData tests writing and reading of a CSV file, and checks that all data is read back correctly into the DataTable. 
 * 
 * Copyright (c) 2020-2022 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
 * for project information  https://djutils.org. The DJUTILS project is
 * distributed under a three-clause BSD-style license, which can be found at
 *  https://djutils.org/docs/license.html. 
 * @author Alexander Verbraeck
 * @author Peter Knoppers
 * @author Wouter Schakel
 */
public class TestCSVData
{
    /**
     * test reading and writing of a CSV file.
     * @throws IOException on error
     * @throws TextSerializationException on unknown data type for (de)serialization
     */
    @Test
    public void testreadWriteCSV() throws IOException, TextSerializationException
    {
        File tempDataFile = File.createTempFile("testdata", ".csv");
        File tempMetaDataFile = File.createTempFile("testmetadata", ".csv");
        tempDataFile.deleteOnExit();
        tempMetaDataFile.deleteOnExit();
        DataColumn column1 = new SimpleDataColumn<>("time", "time, rounded to second [s]", int.class);
        DataColumn column2 = new SimpleDataColumn<>("value", "measured value [m]", double.class);
        DataColumn column3 = new SimpleDataColumn<>("remark", "remark about the measurement", String.class);
        List> columns = new ArrayList<>();
        columns.add(column1);
        columns.add(column2);
        columns.add(column3);
        ListDataTable table1 = new ListDataTable("tableId", "tableDescription", columns);
        table1.addRecord(new Object[] {1, 5.0, "normal"});
        table1.addRecord(new Object[] {2, 10.0, "normal"});
        table1.addRecord(new Object[] {3, 15.0, "normal"});
        table1.addRecord(new Object[] {4, 20.0, "abnormal"});
        CSVData.writeData(tempDataFile.getAbsolutePath(), tempMetaDataFile.getAbsolutePath(), table1);
        DataTable table2 = CSVData.readData(tempDataFile.getAbsolutePath(), tempMetaDataFile.getAbsolutePath());
        assertTrue(table2 instanceof ListDataTable);
        assertEquals(table1.getId(), table2.getId());
        assertEquals(table1.getDescription(), table2.getDescription());
        assertEquals(table1.getNumberOfColumns(), table2.getNumberOfColumns());
        assertArrayEquals(table1.getColumnIds(), table2.getColumnIds());
        assertArrayEquals(table1.getColumnDescriptions(), table2.getColumnDescriptions());
        assertArrayEquals(table1.getColumnDataTypes(), table2.getColumnDataTypes());
        assertArrayEquals(table1.getColumnDataTypeStrings(), table2.getColumnDataTypeStrings());
        Iterator it1 = table1.iterator();
        Iterator it2 = table2.iterator();
        while (it1.hasNext() && it2.hasNext())
        {
            DataRecord r1 = it1.next();
            DataRecord r2 = it2.next();
            assertArrayEquals(r1.getValues(), r2.getValues());
        }
        assertFalse(it1.hasNext());
        assertFalse(it2.hasNext());
    }
}