package net.woodyfolsom.cs6601.p3;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import org.springframework.stereotype.Component;

import net.woodyfolsom.cs6601.p3.domain.Company;
import net.woodyfolsom.cs6601.p3.domain.Headline;
import net.woodyfolsom.cs6601.p3.ngram.NGramModel;
import net.woodyfolsom.cs6601.p3.svc.HeadlineService;

@Component
public class ModelGenerator {
	private static final File stockSymbolsCSV = new File("stock_symbols.csv");

	private static final int INVALID_DATE = 1;
	private static final int IO_EXCEPTION = 2;
	private static final int STOCK_SYMBOL_CSV_NOT_FOUND = 3;

	@Autowired
	HeadlineService mySQLHeadlineServiceImpl;

	private NGramModel ngramModel = new NGramModel();
	
	public static void main(String... args) {

		ApplicationContext context = new FileSystemXmlApplicationContext(
				new String[] { "AppContext.xml" });
		ModelGenerator modelGenerator = context.getBean(ModelGenerator.class);
		DateFormat dateFmt = new SimpleDateFormat("yyyy-MM-dd");
		
		Date startDate = null;
		Date endDate = null;
		Date valStart = null;
		Date valEnd = null;
		try {
			startDate = dateFmt.parse("2012-01-01");
			endDate = dateFmt.parse("2012-03-31");
			valStart = dateFmt.parse("2012-04-01");
			valEnd = dateFmt.parse("2012-04-14");
		} catch (ParseException pe) {
			System.exit(INVALID_DATE);
		}
		
		try {
			List<Company> fortune50 = modelGenerator
					.getFortune50(stockSymbolsCSV);
			for (Company company : fortune50) {
				System.out.println("Getting headlines for Fortune 50 company #"
						+ company.getId() + " (" + company.getName() + ")...");
				List<Headline> trainingSet = modelGenerator.mySQLHeadlineServiceImpl.getHeadlines(company.getStockSymbol(), startDate, endDate);
				System.out.println("Pulled " + trainingSet.size() + " headlines for "
						+ company.getStockSymbol() + " from " + startDate + " to " + endDate);
				List<Headline> validationSet = modelGenerator.mySQLHeadlineServiceImpl.getHeadlines(company.getStockSymbol(), valStart, valEnd);
				
				if (trainingSet.size() == 0) {
					System.out.println("Training dataset contains 0 headlines for " + company.getName() + ", skipping model generation.");
					continue;
				}
				if (validationSet.size() == 0) {
					System.out.println("Validation dataset contains 0 headlines for " + company.getName() + ", skipping model generation.");
					continue;
				}
				
				modelGenerator.ngramModel.reportModel(trainingSet, validationSet);
				System.out.println("Finished " + company.getId() + " / 50");
			}
		} catch (FileNotFoundException fnfe) {
			System.out.println("Stock symbol CSV file does not exist: "
					+ stockSymbolsCSV);
			System.exit(STOCK_SYMBOL_CSV_NOT_FOUND);
		} catch (IOException ioe) {
			System.out.println("Stock symbol CSV file does not exist: "
					+ stockSymbolsCSV);
			System.exit(IO_EXCEPTION);
		}
	}

	private List<Company> getFortune50(File csvFile)
			throws FileNotFoundException, IOException {
		List<Company> fortune50 = new ArrayList<Company>();
		FileInputStream fis = new FileInputStream(csvFile);
		InputStreamReader reader = new InputStreamReader(fis);
		BufferedReader buf = new BufferedReader(reader);
		String csvline = null;
		while ((csvline = buf.readLine()) != null) {
			if (csvline.length() == 0) {
				continue;
			}
			String[] fields = csvline.split(",");
			if (fields.length != 3) {
				throw new RuntimeException(
						"Badly formatted csv file name (3 values expected): "
								+ csvline);
			}
			int id = Integer.valueOf(fields[0]);
			fortune50.add(new Company(id, fields[1], fields[2]));
		}
		return fortune50;
	}
}
