//
//  main.cpp
//  roundRobin
//  Created by Sarvesh Bhatnagar
//  Copyright © 2018 introtoalgo.com. All rights reserved.
//

#include <iostream>
using namespace std;

struct roundRobinStruct{
    int processTime=0;
    string name;
    struct roundRobinStruct *next=NULL;
};



struct roundRobinStruct *temp,*first,*last,*a,*b,*c,*d;


void deleteProcess(struct roundRobinStruct *a, struct roundRobinStruct *b, struct roundRobinStruct *c);

void makeProcess(int time,string name);

void processQueue(int preEmptiveTime);


int main() {
    first = NULL;
    int time,preEmptiveTime;
    time = 0;
    string name;
    preEmptiveTime = 3;
    for (int i = 0; i<5; i++) {
        cout<<"Enter time "<<endl;
        cin>>time;
        cout<<"Enter Process Name "<<endl;
        cin>>name;
        makeProcess(time,name);
    }
    processQueue(3);
    cout<<"Done "<<endl;
    
    return 0;
}

void makeProcess(int time,string name){
    temp = new roundRobinStruct();
    temp->processTime = time;
    temp->name = name;
    if (first == NULL) {
        first = temp;
        temp->next = temp;
    }else{
        last->next = temp;
        temp->next = first;
    }
    last = temp;
}

void processQueue(int preEmptiveTime){
    a = b= first;
    int z = 0;
    c = last;
    while (true) {
        for (int i = 0; i<preEmptiveTime; i++) {
            b->processTime = b->processTime - 1;
            if (b->processTime == 0) {
                d = b;
                deleteProcess(a, d, c);
                b = a;
                a = a->next;
                z = 1;
            }
        }
        if (z != 1) {
            a = a->next;
            b = b->next;
            c = c->next;
        }else{
            z =0;
        }
        if (a == b && b == c) {
            while (b->processTime != 0) {
                b->processTime = b->processTime - 1;
            }
            break;
        }
    }
    
}


void deleteProcess(struct roundRobinStruct *a, struct roundRobinStruct *b, struct roundRobinStruct *c){
    if (a != b || b!= c) {
        c->next = a;
        if (first == b) {
            first = a;
        }
        if (last == b) {
            last = c;
        }
        cout<<"PROCESS "<<b->name<<" Completed "<<endl;
        free(b);
    }
}