#ifndef PROLIFIC_SCHEDULER_HPP
#define PROLIFIC_SCHEDULER_HPP

#include <iostream>
#include <unistd.h>
#include <sys/wait.h>
#include <vector>
#include <algorithm>

#include "Task.hpp"

class ProlificScheduler {
	private:
		int num_workers;
	public:
		ProlificScheduler(int workers) : num_workers(workers) {}

		void execute_task(Task* task) {
			pid_t root = getpid();
			std::vector<pid_t> pids;
			int worker_id=0;

			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){
						break;
					}
					}
				}else{
					if(task!=nullptr){
						task->execute_task(worker_id,num_workers);
					}
					_exit(0);
				}
			}
};

#endif
