/*
 *  Draco Econometrics
 *  Copyright (C) 2006-2008 Approximatrix, LLC
 *  http://www.approximatrix.com
 *  
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.approximatrix.draco.io;

import static org.junit.Assert.*;

import java.io.File;
import java.util.ArrayList;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.approximatrix.draco.io.ImportExport;
import com.approximatrix.draco.datamodel.DateObject;
import com.approximatrix.draco.datamodel.StatTableModel;

public class ImportExportTest {

    private static final String CSV_FILE = "resources/import.csv";
    private static final String TABS_FILE = "resources/import.tabs";
    private static final String DATE_FILE = "resources/date_import.csv";
    
	@Before
	public void setUp() throws Exception {
		
	}

	@After
	public void tearDown() throws Exception {

	}

	@Test
	public void testLoadTextFilenameCSV() {
	
	    Object[] result = ImportExport.LoadText(new File(CSV_FILE),1,1,",",0);
	    assertStandardFileLoaded(result);
	    
	}

	@Test
	public void testLoadTextFilenameTabs() {
	
	    Object[] result = ImportExport.LoadText(new File(TABS_FILE),1,1,"\\t",0);
	    assertStandardFileLoaded(result);
	    
	}
	
	@Test
	public void testCreatePanelModel() {
	
     	Object[] result = ImportExport.LoadText(new File(CSV_FILE),1,1,",",0);
        StatTableModel model = ImportExport.CreatePanelModel((ArrayList)result[0]);
        assertNotNull(model);
        assertEquals(2,model.getColumnCount());
        assertEquals(5,model.getRowCount());
        assertEquals("import0",model.getColumnName(0));
        assertEquals("import1",model.getColumnName(1));
        
        model = ImportExport.CreatePanelModel((ArrayList)result[0], (String[])result[1]);
        assertNotNull(model);
        assertEquals("integer",model.getColumnName(0));
        assertEquals("double",model.getColumnName(1));
        int i=1;
        for(Number value : model.getVariable(0)) {
            assertNotNull(value);
            assertTrue(value instanceof Integer);
            assertEquals(i,value.intValue());
            i++;
        }
        i=1;
        for(Number value : model.getVariable(1)) {
            assertNotNull(value);
            assertTrue(value instanceof Double);
            assertEquals(i,value.intValue());
            i++;
        }
	
	}
	
	@Test
	public void testCreateTimeSeriesModel() {
	    DateObject start = new DateObject(DateObject.YEARLY,1980,0,0,0,0,0);
	    DateObject end = new DateObject(DateObject.YEARLY,2000,0,0,0,0,0);
	    StatTableModel model = ImportExport.CreateTimeSeriesModel(start,end);

	    assertEquals(1,model.getColumnCount());
	    assertEquals(21,model.getRowCount());
        assertEquals("Time",model.getColumnName(0));
        
        for(int i=0;i<21;i++) {
            assertEquals(Integer.toString(1980+i),model.getValueAt(i,0).toString());
        }
	}
    
    @Test
    public void testImportTimeSeriesData() {
	    DateObject start = new DateObject(DateObject.YEARLY,1980,0,0,0,0,0);
	    DateObject end = new DateObject(DateObject.YEARLY,2000,0,0,0,0,0);
	    StatTableModel model = ImportExport.CreateTimeSeriesModel(start,end);
    
        Object[] results = ImportExport.LoadText(new File(DATE_FILE),1,1,",",0);
        
        model = ImportExport.ImportTimeSeriesData(model,(ArrayList)results[0],1,(String[])results[1]);
        assertNotNull(model);
        assertEquals(2,model.getColumnCount());
        assertEquals("Time",model.getColumnName(0));
        assertEquals("value",model.getColumnName(1));
        assertEquals(21,model.getRowCount());
        
        for(int i=0;i<21;i++) {
            if(model.getValueAt(i,0).toString().equals("1982")) {
                assertNotNull(model.getVariable(1).get(i));
                assertEquals(1,model.getVariable(1).get(i).intValue());
            } else if(model.getValueAt(i,0).toString().equals("1984")) {
                assertNotNull(model.getVariable(1).get(i));
                assertEquals(2,model.getVariable(1).get(i).intValue());
            } else if(model.getValueAt(i,0).toString().equals("1989")) {
                assertNotNull(model.getVariable(1).get(i));
                assertEquals(3,model.getVariable(1).get(i).intValue());
            } else
                assertNull(model.getVariable(1).get(i));
        }
    }
    
    private void assertStandardFileLoaded(Object[] result) {
    	    
	    assertNotNull(result);
	    assertEquals(2, result.length);

        assertNotNull(result[1]);	    
	    assertTrue(result[1] instanceof String[]);
	    String[] headers = (String[])result[1];
	    assertEquals(2, headers.length);
	    assertEquals("integer",headers[0]);
	    assertEquals("double",headers[1]);
        
        assertNotNull(result[0]);
        assertTrue(result[0] instanceof ArrayList);
        ArrayList data = (ArrayList)result[0];
        assertEquals(5,data.size());
        for(int i=0;i<data.size();i++) {
            assertNotNull(data.get(i));
            assertTrue(data.get(i) instanceof String[]);
            String[] array = (String[])data.get(i);
            try {
                assertEquals(i+1,new Integer(array[0]).intValue());
            } catch(NumberFormatException nfe) {
                fail("Could not convert to integer");
            }
            try {
                assertEquals(i+1,new Double(array[1]).intValue());
            } catch(NumberFormatException nfe) {
                fail("Could not convert to double");
            }
        }
    }
}
