#include <iostream>
#include <chrono>
#include <random>
#include "row.hpp"
#include "sorting_algorithms.hpp"

using namespace std;
using namespace std::chrono;

// Helper function to run and time each algorithm
template<typename T>
void run_test(string name, void (*sort_func)(row<T>&), const row<T>& original) {
    row<T> test_row = original; // Deep copy to sort the exact same data
    auto start = high_resolution_clock::now();
    sort_func(test_row);
    auto stop = high_resolution_clock::now();
    auto duration = duration_cast<milliseconds>(stop - start);
    cout << name << ": " << duration.count() << " ms" << endl;
}

int main() {
    //Basic test with integers as requested
    int *b = new int[10];
    for (int i=0; i<10; i++) b[i] = rand() % 100;
    row<int> *a = new row<int>(b, 10);

    bubble_sort(*a);
    cout << "Bubble (Small Test): " << *a << endl;


    delete a;
    delete[] b;

    //Generate Report for n=1000 and 10000
    int sizes[] = {1000, 10000};
    for (int n : sizes) {
        cout << "\n--- Testing for size n = " << n << " ---" << endl;
        double* data = new double[n];
        mt19937 rng(1337);
        uniform_real_distribution<double> dist(-10000.0, 10000.0);

        for(int i=0; i<n; i++) data[i] = dist(rng);

        row<double> r(data, n);

        // Timing each algorithm
        run_test("Bubble Sort", bubble_sort, r);
        run_test("Selection Sort", selection_sort, r);
        run_test("Insertion Sort", insertion_sort, r);
        run_test("Merge Sort", merge_sort, r);
        run_test("Quick Sort", quick_sort, r);
        // Enumeration sort is too slow for 10000, only run for 1000
              if(n <= 1000) run_test("Enumeration Sort", enumeration_sort, r);


              delete[] data;
    }
    return 0;
}
