import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.concurrent.ExecutionException;

public class Program {
    private static final int ARRAYS_LENGTH = 1000;
    private static final String PATH_FOR_TESTS = "./tangatarov_ivan_lab_1/src/tests/";
    public static void main(String[] args) throws InterruptedException, ExecutionException {

        int[][] array = GenerateMatrix(ARRAYS_LENGTH);
        int[][] arraySinge = deepCopy(array);
        int[][] arrayThreadPool = deepCopy(array);
        int[][] arrayForkJoin = deepCopy(array);
        System.out.println();
        System.out.println();


        SingleThread single = new SingleThread(arraySinge);
        ExecutorThreadPool executor = new ExecutorThreadPool(Runtime.getRuntime().availableProcessors(), arrayThreadPool);
        ForkJoinT forkJoin = new ForkJoinT(arrayForkJoin);


        System.out.println("result single: ");
        long diapStartTestOne = System.nanoTime();
        int[][] resultSingleThread = single.OperationMatrixSingleThread();
        long diapEndTestOne  = System.nanoTime();
        System.out.println((diapEndTestOne - diapStartTestOne)/1000000 + " ms");


        System.out.println("result threadPool: ");
        long diapStartTestTwo = System.nanoTime();
        int[][] resultThreadPool = executor.operationMatrixThreadPoolExecutor();
        long diapEndTestTwo  = System.nanoTime();
        System.out.println((diapEndTestTwo - diapStartTestTwo)/1000000 + " ms");


        System.out.println("result forkJoin: ");
        long diapStartTestTree =  System.nanoTime();
        int[][] resultForkJoinPool = forkJoin.operationMatrixForkJoinPool();
        long diapEndTestTree  = System.nanoTime();
        System.out.println((diapEndTestTree - diapStartTestTree)/1000000 + " ms");


        runTests(resultSingleThread, resultThreadPool, resultForkJoinPool);
    }

    private static int[][] GenerateMatrix(int size){
        int[][] array = new int[size][size];
        Random rand = new Random();
        for (int i = 0; i < size; i++){
            for (int j = 0; j < size; j++){
                array[i][j] = rand.nextInt(-100, 100);
                //System.out.print(array[i][j] + "  ");
            }
            //System.out.println();
        }
        //System.out.println();
        return array;
    }

    private static void printArray(int[][] array){
        for(int i = 0; i < array.length; i++){
            for (int j = 0; j < array.length; j++){
                System.out.print(array[i][j] + " ");
            }
            System.out.println();
        }
    }

    private static int[][] deepCopy(int[][] original) {
        return Arrays.stream(original).map(int[]::clone).toArray(int[][]::new);
    }

    private static void writeToFile(String fileName, int[][] array) {
        try (FileWriter writer = new FileWriter(fileName)) {
            for (int i = 0; i < array.length; i++) {
                for (int j = 0; j < array[i].length; j++) {
                    writer.write(array[i][j] + " ");
                }
                writer.write("\n");
            }
        } catch (IOException e) {
            System.err.println("Ошибка при записи в файл: " + e.getMessage());
        }
    }

    private static void runTests(int[][] arr1, int[][] arr2, int[][] arr3){
        writeToFile( PATH_FOR_TESTS + "single-test.txt", arr1);
        writeToFile(PATH_FOR_TESTS + "threadPool-test.txt", arr2);
        writeToFile(PATH_FOR_TESTS + "forkJoin-test.txt", arr3);
    }
}