package edu.neu.coe.info6205.sort.par;

import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.*;
import java.util.concurrent.ForkJoinPool;

/**
 * This code has been fleshed out by Ziyao Qiao. Thanks very much.
 * TODO tidy it up a bit.
 */
public class Main {

    public static void main(String[] args) {

//        // parallelism experiment
//        System.out.println("Available processors: "+Runtime.getRuntime().availableProcessors());
//        processArgs(args);
//        Random random = new Random();
//        int[] array = new int[2000000];
//        int p = ParSort.myPool.getParallelism();
//        String result = "";
//
//        for (int j = 0; j < 3; j++) {
//            ParSort.cutoff = (int) (5000 * Math.pow(10,j));
//            for (int i = 0; i < array.length; i++) array[i] = random.nextInt(10000000);
//            long time;
//            long startTime = System.currentTimeMillis();
//            for (int t = 0; t < 10; t++) {
//                ParSort.sort(array, 0, array.length);
//            }
//            long endTime = System.currentTimeMillis();
//            time = (endTime - startTime);
//            result = result + "," +(double) time/10;
//
//            System.out.println("Parallelism: "+p+"\t\tcutoff: " + (ParSort.cutoff) + "\t\t10times Time:" + time + "ms");
//        }
//        try {
//            FileOutputStream fis = new FileOutputStream("./src/degree2.csv",true);
//            OutputStreamWriter isr = new OutputStreamWriter(fis);
//            BufferedWriter bw = new BufferedWriter(isr);
//            String content = p + result + "\n";
//            bw.write(content);
//            bw.flush();
//            bw.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }


//        // cutoff experiment
//        processArgs(args);
//        Random random = new Random();
//        int[] array = new int[2000000];
//        ArrayList<Long> timeList = new ArrayList<>();
//        for (int j = 50; j < 1000; j++) {
//            ParSort.cutoff = 1000 * (j + 1);
//            for (int i = 0; i < array.length; i++) array[i] = random.nextInt(10000000);
//            long time;
//            long startTime = System.currentTimeMillis();
//            for (int t = 0; t < 10; t++) {
////                for (int i = 0; i < array.length; i++) array[i] = random.nextInt(10000000);
//                ParSort.sort(array, 0, array.length);
//            }
//            long endTime = System.currentTimeMillis();
//            time = (endTime - startTime);
//            timeList.add(time);
//            System.out.println("cutoff: " + (ParSort.cutoff) + "\t\t10times Time:" + time + "ms");
//        }
//        try {
//            FileOutputStream fis = new FileOutputStream("./src/result.csv");
//            OutputStreamWriter isr = new OutputStreamWriter(fis);
//            BufferedWriter bw = new BufferedWriter(isr);
//            int j = 0;
//            bw.write("cutoff ratio,time\n");
//            for (long i : timeList) {
//                String content = (double) 1000 * (j + 51) / 2000000 + "," + (double) i / 10 + "\n";
//                j++;
//                bw.write(content);
//                bw.flush();
//            }
//            bw.close();
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }

        // efficacy
        processArgs(args);
        Random random = new Random();
        String result= "";

        for (int n = 1; n < 11; n++) {
            int num = 2000000*n;
            int[] array = new int[num];

            for (int j = 0; j < 3; j++) {
                ParSort.cutoff = (int) (num/8 * Math.pow(2,j));
                for (int i = 0; i < array.length; i++) array[i] = random.nextInt(10000000);
                long time;
                long startTime = System.currentTimeMillis();
                for (int t = 0; t < 10; t++) {
                    ParSort.sort(array, 0, array.length);
                }
                long endTime = System.currentTimeMillis();
                time = (endTime - startTime);
                result = result + "," +(double) time/10;

                System.out.println("Elements: "+num+"\t\tcutoff: " + (ParSort.cutoff) + "\t\tMergesort Time:" + time + "ms");
            }
        }

        try {
            FileOutputStream fis = new FileOutputStream("./src/result.csv");
            OutputStreamWriter isr = new OutputStreamWriter(fis);
            BufferedWriter bw = new BufferedWriter(isr);
            String content = "Mergesort" + result + "\n";
            bw.write(content);
            bw.flush();
            bw.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static void processArgs(String[] args) {
        String[] xs = args;
        while (xs.length > 0)
            if (xs[0].startsWith("-")) xs = processArg(xs);
    }

    private static String[] processArg(String[] xs) {
        String[] result = new String[0];
        System.arraycopy(xs, 2, result, 0, xs.length - 2);
        processCommand(xs[0], xs[1]);
        return result;
    }

    private static void processCommand(String x, String y) {
        if (x.equalsIgnoreCase("N")) setConfig(x, Integer.parseInt(y));
        else
            // TODO sort this out
            if (x.equalsIgnoreCase("P")) //noinspection ResultOfMethodCallIgnored
                ForkJoinPool.getCommonPoolParallelism();
    }

    private static void setConfig(String x, int i) {
        configuration.put(x, i);
    }

    @SuppressWarnings("MismatchedQueryAndUpdateOfCollection")
    private static final Map<String, Integer> configuration = new HashMap<>();


}
