package ec.app.regression.testcases;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import library.semantics.TestCase;

import ec.EvolutionState;
import ec.util.Parameter;

public abstract class CSVFactory<T> extends TestCaseFactory {

	private static final Parameter trainingCSV = new Parameter("testCases.trainingCsv");
	private static final Parameter testingCSV = new Parameter("testCases.testingCsv");

	@Override
	public List<TestCase<T>> compute(EvolutionState state) {
		return null;
	}

	protected List<TestCase<T>> compute(EvolutionState state, Parameter param) {

		File csvFile = state.parameters.getFile(param, null);
		List<TestCase<T>> list = new ArrayList<TestCase<T>>();
		BufferedReader reader = null;
		String line;
		String[] fields;
		T[] x;

		try {
			reader = new BufferedReader(new InputStreamReader(new FileInputStream(csvFile)));

			line = reader.readLine(); // first line contains headers

			x = this.newArray(line.split(";").length - 1);

			while ((line = reader.readLine()) != null) {
				fields = line.split(";");
				assert fields.length == x.length + 1;

				T y = this.parse(fields[0]);
				for (int i = 1; i < fields.length; ++i) {
					x[i - 1] = this.parse(fields[i]);
				}

				list.add(new TestCase<T>(y, (T[]) x.clone()));
			}

		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (reader != null)
					reader.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

		return list;
	}

	public List<TestCase<T>> generateTraining(final EvolutionState state) {
		return this.compute(state, trainingCSV);
	}

	public List<TestCase<T>> generateTest(final EvolutionState state) {
		return this.compute(state, testingCSV);
	}

	protected abstract T parse(String x);

	protected abstract T[] newArray(int size);
}
