package pi;

import java.io.*;
import java.lang.reflect.Constructor;

public class Main {

    private static final String PI_FILE = "/Users/amcasey/Misc/Pi/pi1M.txt";

    public static void main(String[] args) {
        System.out.println("JFlex - Good:  " + getFreqs(JFlexGoodPiScanner.class, PI_FILE));
        System.out.println("JFlex - Bad :  " + getFreqs(JFlexBadPiScanner.class, PI_FILE));
        System.out.println("ML - Good   :  " + getFreqs(MLGoodPiScanner.class, PI_FILE));
        System.out.println("ML - Bad    :  " + getFreqs(MLBadPiScanner.class, PI_FILE));
        System.out.println("ML - Bad Tw :  " + getFreqs(MLBadPiScanner_Tweaked.class, PI_FILE));
        System.out.println("MLN - Good  :  " + getFreqs(MLNGoodPiScanner.class, PI_FILE));
        System.out.println("MLN - Bad   :  " + getFreqs(MLNBadPiScanner.class, PI_FILE));
    }

    private static Result getFreqs(Class<? extends PiScanner> clazz, String fileName) {
        try {
            return getFreqs(clazz, new BufferedReader(new FileReader(fileName)));
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private static Result getFreqs(Class<? extends PiScanner> clazz, Reader reader) {
        try {
            Constructor<? extends PiScanner> ctor = clazz.getConstructor(Reader.class);
            PiScanner scanner = (PiScanner) ctor.newInstance(reader);
            long startTime = System.currentTimeMillis();
            int[] freqs = scanner.getFreqs();
            scanner.stop(); //TODO: do this AFTER endTime?
            long endTime = System.currentTimeMillis();
            Result result = new Result(freqs, startTime, endTime);
            reader.close();
            return result;
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
    }

    private static void print(int[] array) {
        print(array, new PrintWriter(System.out));
    }

    private static void print(int[] array, PrintWriter writer) {
        writer.print("[");
        boolean first = true;
        for(int n : array) {
            if(!first) {
                writer.print(", ");
            }
            writer.print(n);
            first = false;
        }
        writer.print("]");
        writer.flush();
    }

    private static class Result {
        final int[] freqs;
        long time;

        public Result(int[] freqs, long startTime, long endTime) {
            this.freqs = freqs;
            this.time = endTime - startTime;
        }

        public String toString() {
            StringWriter strWriter = new StringWriter();
            PrintWriter writer = new PrintWriter(strWriter);
            writer.print(time + ":\t");
            print(freqs, writer);
            return strWriter.toString();
        }
    }
}