#include "CollectiveScheduler.hpp"
#include <sys/wait.h>
#include <cmath>

CollectiveScheduler::CollectiveScheduler() { }
CollectiveScheduler::~CollectiveScheduler() { }

int CollectiveScheduler::partition(double* s, int low, int high) {
    double pivot = s[high];
        int i = low - 1;
        for (int j = low; j < high; ++j) {
        if (s[j] < pivot) {
               ++i;
               double temp = s[i];
               s[i] = s[j];
               s[j] = temp;
               }
        }
double temp = s[i + 1];
s[i + 1] = s[high];
s[high] = temp;
return i + 1;
}


void CollectiveScheduler::quick_sort_recursive(double* s, int low, int high) {
    if (low < high) {
            int pi = partition(s, low, high);
            quick_sort_recursive(s, low, pi - 1);
            quick_sort_recursive(s, pi + 1, high);
            }
}

void CollectiveScheduler::execute(int levels, int rows, double* data, int n) {
        pid_t root = getpid();
        for (int i = 0; i < levels; ++i) {
                fork();
        }
        if (getpid() != root) {
                int worker_id = getpid() % root;
                int worker_count = (int)pow(2, levels) - 1;
                if (worker_count <= 0) worker_count = 1;
                for (int r = 0; r < rows; r++) {
                if (r % worker_count == worker_id % worker_count) {
                         quick_sort_recursive(data + (r * n), 0, n - 1);
                         }
                 }
                _exit(0);
                } 
                else {
                        while (waitpid(-1, NULL, 0) > 0);
                            }
 }
