package Sorting;

import java.util.Scanner;
import java.util.ArrayList;
import java.util.InputMismatchException;
//import java.time.temporal.ChronoUnit;
/**
 * This class contains the main method and presents an interface for the user to
 * compare sorting algorithm efficiencies. The user will be able to generate files
 * of random numbers, and to select a set of algorithms to test on a file of random
 * numbers.
 */
public class AlgorithmTester{

    final static Scanner sc = new Scanner(System.in);
    static int input;
    static boolean quit = false;
    public static void main(String[] args) {
        while(!quit){
             System.out.println("\nSORTING ALGORITHM TESTER");
            System.out.println("Please select an option:");
            System.out.println("1) Make a file of random numbers");
            System.out.println("2) Sort a file of random numbers");
            System.out.println("0) Exit");
            try{
                input = sc.nextInt();
         //Using the new switch syntax introduced in JDK 13
        //this is a switch expression (lambda expression) rather than a switch statement
                switch(input){
                    case 1 -> makeFile();
                    case 2 -> sortFile();
                    case 0 -> quit=true;
                    default -> System.out.println("Invalid input");
                }
                /*
                non-lambda expresstion version looks like this
                switch(input){
                    case 1:
                        makeFile();
                        break;
                    case 2:
                        sortFiler();
                        break;
                    case 0:
                        quit=true;
                        break;
                    default:
                        System.out.println("Invalid input");
                        break;
                }
                */
            } catch(InputMismatchException ex){
                System.out.println("Invalid input");
            }
        }
        sc.close();
    }

    private static void makeFile(){
        String filename;
        int count;
        int min;
        int max;
        try{
            System.out.print("\nPlease enter a file name: ");
            filename = sc.next();
            System.out.println("How many random numbers?");
            count = sc.nextInt();
            System.out.println("Minimum value?");
            min = sc.nextInt();
            System.out.println("Maximum value?");
            max = sc.nextInt();
            var randomMaker = new RandomNumberFileMaker(filename, count, min, max);
            randomMaker.writeFile();
        } catch(InputMismatchException ex){
                System.out.println("Invalid input");
            }
    }

    private static void sortFile(){
        String filename;
        int input;
        boolean ready=false;
        boolean print=false;
        String[] sortingAlgoNames = {"bubble","selection","insertion","counting","quick","merge"};
        boolean[] sortingAlgoChoices = new boolean[sortingAlgoNames.length];
        System.out.print("\nPlease enter file name: ");
        filename = sc.next();
        while(!ready){
            try{
                System.out.println("\nEnter the number of an algorithm you wish to use.");
                System.out.println("Enter the number again to deselect an algorithm.");
                for(int i=0;i<sortingAlgoNames.length;i++){
                    int num=i+1;
                    System.out.print(num+") "+sortingAlgoNames[i]);
                    if(sortingAlgoChoices[i]){
                        System.out.print(" *\n");
                    }
                    else{
                        System.out.print("\n");
                    }
                }
                System.out.println("Enter 0 to continue when all desired algorithms have been selected.");
                input = sc.nextInt();
                if(input>0&&input<=sortingAlgoChoices.length){
                    sortingAlgoChoices[input-1]=!sortingAlgoChoices[input-1];
                }
                else if(input==0){
                    ready=true;
                }
                else{
                    System.out.println("Invalid input");
                }
            }catch(InputMismatchException ex){
                System.out.println("Invalid input");
            }
        }
        try{
            System.out.println("\nPrint sorted list?");
            System.out.println("1) Yes");
            System.out.println("2) No");
            input = sc.nextInt();
            switch(input){
                case 1 -> print=true;
                case 2 -> print=false;
                default -> System.out.println("Invalid input, defaulting to no");
            }
        }catch(InputMismatchException ex){
            System.out.println("Invalid input, defaulting to no");
        }
        boolean bubble=sortingAlgoChoices[0];
        boolean selection=sortingAlgoChoices[1];
        boolean insertion=sortingAlgoChoices[2];
        boolean counting=sortingAlgoChoices[3];
        boolean quick=sortingAlgoChoices[4];
        boolean merge=sortingAlgoChoices[5];
        ArrayList<SortResult> results = new ArrayList<SortResult>();
        
        if(bubble){
            BubbleSorter bubSorter = new BubbleSorter(filename);
            results.add(bubSorter.measuredSort());
        }
        if(selection){
            SelectionSorter selSorter = new SelectionSorter(filename);
            results.add(selSorter.measuredSort());
        }
        if(insertion){
            InsertionSorter inSorter = new InsertionSorter(filename);
            results.add(inSorter.measuredSort());
        }
        if(counting){
            CountingSorter countSorter = new CountingSorter(filename);
            results.add(countSorter.measuredSort());
        }
        if(quick){
            QuickSorter qSorter = new QuickSorter(filename);
            results.add(qSorter.measuredSort());
        }
        if(merge){
            MergeSorter mSorter = new MergeSorter(filename);
            results.add(mSorter.measuredSort());
        }
        for(SortResult e: results){
            if(print){
                for(int i: e.getSortedArray()){
                    System.out.print(i+" ");
                }
            }
            System.out.println("\n"+e.getSortType()+" sort took:");
            System.out.println(e.getComparisonsUsed()+" comparisons");
            System.out.println(e.getWritesUsed()+" write operations");
            System.out.println(e.getTimeUsed()+" milliseconds");
        }
        
    }
}