#include <iostream>
#include <cstdlib>
#include <ctime>
#include <sys/mman.h> 
#include <chrono> 

#include "ProlificScheduler.hpp"
#include "CollectiveScheduler.hpp"
#include "SortTask_mmap.hpp"

int main() {
    srand(time(0));
    // --- ΡΥΘΜΙΣΕΙΣ ΣΥΓΚΡΙΣΗΣ ---
                int n = 1000;         // Μεγάλος πίνακας 1000x1000 για να φανεί ο χρόνος
                int num_workers = 7;  // 7 Εργάτες για τον Prolific
                int levels = 3;       // 3 Επίπεδα για τον Collective (2^3 - 1 = 7 εργάτες)

                std::cout << "=== ΣΥΓΚΡΙΣΗ SCHEDULERS ===\n";
                std::cout << "Διαστάσεις Πίνακα: " << n << "x" << n << "\n";
                std::cout << "Αριθμός Εργατών: " << num_workers << " (Prolific) vs " << (pow(2, levels) - 1) << " (Collective)\n\n";

                // 1. Δέσμευση Κοινόχρηστης Μνήμης
                int* A = (int*) mmap(NULL, n * n * sizeof(int), PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);

                // Γεμίζουμε τον πίνακα
                for (int i = 0; i < n * n; ++i) {
                A[i] = (rand() % 2001) - 1000;
                }

                SortTask mySortTask(A, n);

                // --- ΤΕΣΤ 1: PROLIFIC SCHEDULER ---
                ProlificScheduler prolific(num_workers);

                auto start_p = std::chrono::high_resolution_clock::now();
                prolific.execute(&mySortTask);
                auto end_p = std::chrono::high_resolution_clock::now();

                std::chrono::duration<double, std::milli> elapsed_p = end_p - start_p;
//                std::cout << "Χρόνος Prolific:   " << elapsed_p.count() << " ms\n";;
                                                                                      
                                                                                      
                // (Προαιρετικά: Ανακατεύουμε ξανά τον πίνακα για να είναι δίκαιο το τεστ)
                for (int i = 0; i < n * n; ++i) { A[i] = (rand() % 2001) - 1000; }

                // --- ΤΕΣΤ 2: COLLECTIVE SCHEDULER ---
                CollectiveScheduler collective(levels);
                auto start_c = std::chrono::high_resolution_clock::now();
                collective.execute(&mySortTask);
                auto end_c = std::chrono::high_resolution_clock::now();
                std::chrono::duration<double, std::milli> elapsed_c = end_c - start_c;
                std::cout << "Χρόνος Collective: " << elapsed_c.count() << " ms\n";;
                std::cout << "Χρόνος Prolific:   " << elapsed_p.count() << " ms\n";;

                munmap(A, n * n * sizeof(int));
                return 0;
                }
