#ifndef PROLIFIC_SCHEDULER_HPP
#define PROLIFIC_SCHEDULER_HPP

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <vector>
#include <algorithm>
#include "task.hpp" // Κάνουμε include τη διεπαφή μας

class ProlificScheduler {
private:
    int num_workers;

    public:
        ProlificScheduler(int workers) : num_workers(workers) {}

        // Τώρα δέχεται έναν δείκτη (pointer) σε ένα αντικείμενο τύπου Task                
        void execute(Task* task) {
        	pid_t root = getpid();
        	std::vector<pid_t> pids;
	       	int worker_id;

       		for (int i = 0; i < num_workers; i++) {
			if (getpid() !=root) {
			break;
       		}

	       	pid_t pid = fork();

       		if(pid==0) {
       			worker_id = i;
	       		break;
       		} else if (pid >0) {
       			pids.push_back(pid);
       		}else{
       			std::cerr<< "Fork failed \n";
       			}
       	}

       if(getpid() == root) {
       	int status;
       	while(!pids.empty()){
       		pid_t finished = waitpid(-1,&status,0);
       		if (finished >0) {
       			std::cout<<"Reaped PID " << finished << "\n";
       			pids.erase(std::remove(pids.begin() , pids.end() ,finished), pids.end());
       		}else if(finished== - 1 && errno == ECHILD) {
       			break;
       		}
       	}
        }else {
        if (task!=nullptr) {
        	task->execute_task(worker_id,num_workers);
        }
        _exit(0);
       }
      }
};

#endif
  
