package savinov_roman_lab_1;

import java.util.Arrays;

//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter
public class Main {

    public static boolean isEqual(int[][] array1, int[][] array2){
        if(array1.length != array2.length || array1[0].length != array2[0].length){
            return false;
        }
        for(int i = 0; i < array1.length;i++){
            for(int j = 0; j < array1[0].length; j++){
                if(array1[i][j] != array2[i][j]){
                    return false;
                }
            }
        }
        return true;
    }
    private static int[][] generateTwoDimArr(int maximumDigit, int rows, int cols){
        int[][] result = new int[rows][cols];
        for(int i = 0; i < rows; i++){
            for(int j = 0; j < cols; j++){
                result[i][j] = (int) (Math.random()*maximumDigit);
            }
        }
        return result;
    }
    private static void copyTo(int[][] sourceArray, int[][] destArray){
        for(int i = 0; i < sourceArray.length; i++){
            destArray[i] = Arrays.copyOf(sourceArray[i],sourceArray[i].length);
        }
    }
    private static void test(){
        int[][] testArray = {
                {3,     8,    4, 10,  2,  1,102},
                {2,   423,   41, 53,123,421,123},
                {1312,214,    5,  1, 23,  4,  5}
        };
        int[][] testArray2 = new int[testArray.length][];
        int[][] testArray3 = new int[testArray.length][];
        copyTo(testArray,testArray2);
        copyTo(testArray,testArray3);
        testArray = ArrayController.getSortedTwoDimArr(testArray);
        testArray2 = ArrayController.parallelSortedTwoDimArr(testArray2);
        testArray3 = ArrayController.secondParallelSortedTwoDimArr(testArray3);
        int[][] resultOfTest = {
                {  1,   2,     3,  4,      8, 10, 102},
                {421, 123,    2,  41,    423, 53, 123 },
                {  4,  23, 1312,   5,    214, 1,   5}
        };
        if(!isEqual(testArray,resultOfTest) || !isEqual(testArray2,resultOfTest) || !isEqual(testArray3,resultOfTest) ){
            System.out.println("Контрольная точка не пройдена");
            return;
        }
        else{
            System.out.println("Контрольная точка пройдена. Можете пройти за бонусом.");
        }
        int[][] testArrayN = {
                { 7,  12,   5,  2,  98, 33,  9},
                { 45,  3,  67, 89,   1,  4,  8},
                {200, 50, 150, 25, 175, 75,  5}
        };
        testArray2 = new int[testArrayN.length][];
        testArray3 = new int[testArrayN.length][];
        copyTo(testArrayN, testArray2);
        copyTo(testArrayN, testArray3);
        testArrayN = ArrayController.getSortedTwoDimArr(testArrayN);
        testArray2 = ArrayController.parallelSortedTwoDimArr(testArray2);
        testArray3 = ArrayController.secondParallelSortedTwoDimArr(testArray3);

        resultOfTest =  new int[][]{
                { 2,   5,   7,   9,  12,  33,  98 },
                { 89, 67,  45,   8,   3,   4,   1 },
                { 25,150, 200,   5,  50,  75, 175 }
        };
        if(!isEqual(testArrayN, resultOfTest) || !isEqual(testArray2, resultOfTest) || !isEqual(testArray3, resultOfTest)) {
            System.out.println("Контрольная точка не пройдена");
        } else {
            System.out.println("Контрольная точка пройдена. Можете пройти за бонусом.");
        }
    }
    public static void main(String[] args) {
        int rows = 5000;
        int cols = 5000;
        test();
        // Засекаем время до сортировки

        int[][] originalArray = generateTwoDimArr(100,rows,cols);
        int[][] firstArray = new int[rows][cols];
        int[][] secondArray = new int[rows][cols];
        int[][] thirdArray = new int[rows][cols];
        copyTo(originalArray,firstArray);
        long startTime = System.nanoTime();
        ArrayController.getSortedTwoDimArr(firstArray);
        System.out.println(Runtime.getRuntime().availableProcessors());
        long endTime = System.nanoTime();
        System.out.println("Время выполнения без потоков: " + (endTime - startTime) / 1_000_000.0 + " мс");
        firstArray = null;
        copyTo(originalArray, secondArray);
        long startTime1 = System.nanoTime();
        ArrayController.parallelSortedTwoDimArr(secondArray);
        long endTime1 = System.nanoTime();

        System.out.println("Время выполнения с потоками ThreadExecutor: " + (endTime1 - startTime1) / 1_000_000.0 + " мс");
        secondArray = null;
        copyTo(originalArray, thirdArray);
        originalArray= null;
        long startTime2 = System.nanoTime();
        ArrayController.secondParallelSortedTwoDimArr(thirdArray);
        long endTime2 = System.nanoTime();
        System.out.println("Время выполнения с потоками ForkJoinPool: " + (endTime2 - startTime2) / 1_000_000.0 + " мс");
        thirdArray = null;


    }
}