#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <unistd.h>
#include <time.h>
#include <signal.h>
#include <sys/wait.h>

union semun{
    int val;
}arg;

typedef struct{
    long tip;
    int cvorovi[12];
    int operacija;
    int rezultat;
    int niz[4];
    int rd_broj;
    int pid;
    int rez[3];
}Operacija;


enum{PRISTUP_KLASTERU,PRIJAVA_TRI_REDNA_CVORA,OBAVLJENI_ZADACI};

int main(){

    key_t msgkey=ftok("./init.c",'Q');
    int msgid=msgget(msgkey,IPC_CREAT|0666);

    key_t shmkey=ftok("./init.c",'M');
    int shmid=shmget(shmkey,sizeof(Operacija),IPC_CREAT|0666);

    key_t semkey=ftok("./init.c",'S');
    int semid=semget(semkey,3,IPC_CREAT|0666);

    struct sembuf P={0,-1,0},V={0,1,0};
    Operacija *op=(Operacija*) shmat(shmid,NULL,0);

    V.sem_num=PRIJAVA_TRI_REDNA_CVORA;
    V.sem_op=1;
    semop(semid,&V,1);

    Operacija op1;
    Operacija op2;
    Operacija op3;
    msgrcv(msgid,&op1,sizeof(op)-sizeof(long),3,0);
    msgrcv(msgid,&op2,sizeof(op)-sizeof(long),3,0);
    msgrcv(msgid,&op3,sizeof(op)-sizeof(long),3,0);
    printf("Redni cvorovi su dobili redni broj i operaciju\n");
   
    for(int i=0;i<4;i++){
        op1->niz[i]=op->cvorovi[i];
    }
    for(int i=4;i<8;i++){
        op2->niz[i]=op->cvorovi[i];
    }
    for(int i=8;i<12;i++){
        op3->niz[i]=op->cvorovi[i];
    }

    if(op->operacija==1){
        for(int i=0;i<4;i++){
            op1.rezultat+=op1.niz[i];
            op2.rezultat+=op1.niz[i];
            op3.rezultat+=op1.niz[i];
            
        }
        
        sleep(1);
    }
    else if(op.operacija==2){
        int broj1=1,broj2=1,broj3=1;
        for(int i=0;i<4;i++){
            broj1*=op1.niz[i];
            broj2*=op1.niz[i];
            broj3*=op1.niz[i];
            if(i==3){
                op1.rezultat+=broj1;
                op2.rezultat+=broj2;
                op3.rezultat+=broj3;
            }
            
        }
        
        sleep(1);
    }
    else if(operacija==3){
        op1.rezultat=op1.niz[0];
        op2.rezultat=op2.niz[0];
        op3.rezultat=op3.niz[0];
        for(int i=1;i<4;i++){
            if(op1.niz[i]>op1.rezultat){
                op1.rezultat=op1.niz[i];
            }
            if(op2.niz[i]>op2.rezultat){
                op2.rezultat=op2.niz[i];
            }
            if(op3.niz[i]>op3.rezultat){
                op3.rezultat=op3.niz[i];
            }
        }
        
        sleep(1);
    }
    else{
        op1.rezultat=op1.niz[0];
        op2.rezultat=op2.niz[0];
        op3.rezultat=op3.niz[0];
        for(int i=1;i<4;i++){
            if(op1.niz[i]<op1.rezultat){
                op1.rezultat=op1.niz[i];
            }
            if(op2.niz[i]<op2.rezultat){
                op2.rezultat=op2.niz[i];
            }
            if(op3.niz[i]<op3.rezultat){
                op3.rezultat=op3.niz[i];
            }
        }
        sleep(1);
    }

    op1.tip=3;
    op2.tip=3;
    op3.tip=3;
    msgsnd(msgid,&op1,sizeof(op)-sizeof(long),0);
    msgsnd(msgid,&op2,sizeof(op)-sizeof(long),0);
    msgsnd(msgid,&op3,sizeof(op)-sizeof(long),0);
    
    P.sem_num=OBAVLJENI_ZADACI;
    P.sem_op=1;
    semop(semid,&P,1);

    return 0;
}