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.nio.charset.Charset;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
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.svc.HeadlineService;

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

	private static final int INVALID_END_DATE = 1;
	private static final int INVALID_MODE = 2;
	private static final int INVALID_START_DATE = 3;
	private static final int IO_EXCEPTION = 4;
	private static final int NO_ARGS = 5;
	private static final int STOCK_SYMBOL_CSV_NOT_FOUND = 6;

	@Autowired
	HeadlineService mySQLHeadlineServiceImpl;
	@Autowired
	HeadlineService yahooHeadlineServiceImpl;

	private static void printUsage() {
		System.out
				.println("Usage: java -jar cs6601p3.jar [insert|delete] mm/dd/yyyy-mm/dd/yyyy");
	}

	private enum MODE {
		insert, invalid, delete
	}

	public static void main(String... args) {
		MODE mode = MODE.invalid;
		if (args.length != 2) {
			printUsage();
			System.exit(NO_ARGS);
		} else {
			try {
				mode = MODE.valueOf(args[0]);
			} catch (Exception ex) {
				System.out.println("Invalid mode: " + args[0]);
			}
		}

		if (mode == MODE.invalid) {
			System.exit(INVALID_MODE);
		}

		if (mode == MODE.delete) {
			System.out.println("Mode = delete.  All data will be purged from HEADLINES table.  Continue? [y/n]");
			byte[] buf = new byte[10];
			try {
				int read = System.in.read(buf,0,10);
				String conf = new String(buf,0,read,Charset.defaultCharset());
				System.out.println("CONF = '" + conf +"'");
				if (conf.charAt(0) == 'y') {
					System.out.println("Delete mode confirmed.  Continuing...");
					System.exit(0);
				} else {
					System.out.println("Delete mode cancelled.");
					System.exit(0);
				}
			} catch (IOException ioe) {
				System.exit(IO_EXCEPTION);
			}
		}
		String[] dateFields = args[1].split("-");
		DateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
		Date startDate = null;
		try {
			startDate = dateFormat.parse(dateFields[0]);
		} catch (ParseException pe) {
			System.out.println("Invalid start date: " + dateFields[0]);
			System.exit(INVALID_START_DATE);
		}
		Date endDate = null;
		try {
			endDate = dateFormat.parse(dateFields[1]);
		} catch (ParseException pe) {
			System.out.println("Invalid end date: " + dateFields[0]);
			System.exit(INVALID_END_DATE);
		}

		ApplicationContext context = new FileSystemXmlApplicationContext(
				new String[] { "AppContext.xml" });
		HeadlinePuller headlinePuller = context.getBean(HeadlinePuller.class);
		Calendar calendar = Calendar.getInstance();
		try {
			List<Company> fortune50 = headlinePuller
					.getFortune50(stockSymbolsCSV);
			for (Company company : fortune50) {
				System.out.println("Getting headlines for Fortune 50 company #"
						+ company.getId() + " (" + company.getName() + ")...");
				Date today;
				for (calendar.setTime(startDate); (today = calendar.getTime())
						.compareTo(endDate) <= 0; calendar
						.add(Calendar.DATE, 1)) {
					List<Headline> headlines = headlinePuller.pullHeadlines(
							company.getStockSymbol(), today);
					int[] updates = headlinePuller.mySQLHeadlineServiceImpl.insertHeadlines(headlines);
					System.out.println(updates.length + " rows updated");
				}
			}
		} 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<Headline> pullHeadlines(String stockSymbol, Date date) {
		List<Headline> headlines = yahooHeadlineServiceImpl.getHeadlines(
				stockSymbol, date);
		System.out.println("Pulled " + headlines.size() + " headlines for " + stockSymbol + " on " + date);
		return headlines;
	}

	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;
	}
}
