/*
 * main.c
 *
 *  Created on: Oct 21, 2010
 *      Author: blackpanther
 */



#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include <sys/types.h>
#include <sys/wait.h>

char* cleanNewLine(char * str) {
    //printf("\t<Debug> '%s'\n\t<Still Debug> taille-2 : '%d' taille-1 : '%d' saut ligne : '%d' fin de char : '%d'\n",str,str[strlen(str)-2],str[strlen(str)-1],'\n','\0');
    if (str[strlen(str) - 1] == '\n')
        str[strlen(str) - 1] = '\0';
    return str;
}

int main(int argc,
        char* argv[],
        char* envp[]) {
    pid_t sonId;
    int dataSender[2];
    int notification[2];
    FILE *theSenderOut;
    FILE *theSenderIn;

    FILE *theNotificationOut;
    FILE *theNotificationIn;

    // create communication
    pipe(dataSender);
    pipe(notification);

    theSenderOut = fdopen(dataSender[1], "w");
    theSenderIn = fdopen(dataSender[0], "r");

    theNotificationOut = fdopen(notification[1], "w");
    theNotificationIn = fdopen(notification[0], "r");

    printf("(pid:'%d',ppid:'%d') Hey, I'm big brother, and i'm gonna create a son \n\t(p.s my name is '%s')!\n", getpid(), getppid(), argv[0]);
    printf("(pid:'%d',ppid:'%d')  Okay, now waiting some time to let my son finish its job\n", getpid(), getppid());

    sonId = fork();

    switch (sonId) {
        case -1:
            perror("Problem during forking");
            return (-1);
        case 0:
        {
            // no writing here
            close(dataSender[1]);
            //no reading here
            close(notification[0]);

            char programPath[300] = {'\0'};
            char programName[100] = {'\0'};

            int counter = 0;
            char collection[10][100] = {
                {0}};

            printf("(pid:'%d',ppid:'%d') Let's wait for my dad's instructions\n", getpid(), getppid());
            fgets(programPath, 300, theSenderIn);

            //notify
            fputs("notification 1\n", theNotificationOut);
            fflush(theNotificationOut);

            printf("(pid:'%d',ppid:'%d') Program path received : '%s'\n", getpid(), getppid(), cleanNewLine(programPath));
            fgets(programName, 100, theSenderIn);

            //notify
            fputs("notification 2\n", theNotificationOut);
            fflush(theNotificationOut);

            printf("(pid:'%d',ppid:'%d') Program name received : '%s'\n", getpid(), getppid(), cleanNewLine(programName));
            do {
                counter++;
                memset(collection[counter], '\0', 100 * sizeof (char));
                fgets(collection[counter], 75, theSenderIn);

                //notify
                fputs("notification x\n", theNotificationOut);
                fflush(theNotificationOut);

                
                printf("(pid:'%d',ppid:'%d') Program %d variabe received : '%s'\n", getpid(), getppid(), counter, cleanNewLine(collection[counter]));
            } while (strcmp(collection[counter], "LAST") != 0 && counter < 10);

/*
            collection[counter] = (char *)NULL;
*/

            execl(programPath, programName, NULL);
            break;
        }
        default:
        {
            //no reading here
            close(dataSender[0]);
            //no writing here
            close(notification[1]);

            char programPath[] = "/home/blackpanther/cours-progsys/TD/TD 01 - Fork - Pipe - Execl/Dummy Program/dist/Debug/GNU-Linux-x86/dummy_program\n";
            char programName[] = "DummyProgram\n";
            char* programParameters[] = {
                "a\n",
                "b\n",
                "c\n",
                "LAST\n",
                NULL
            };
            char notificator[100] = {0};
            char ** cursor;

            cursor = programParameters;

            printf("(pid:'%d',ppid:'%d') Let's give its some instructions \n", getpid(), getppid());

            printf("(pid:'%d',ppid:'%d') Sending program path\n", getpid(), getppid());
            fputs(programPath, theSenderOut);
            fflush(theSenderOut);

            printf("(pid:'%d',ppid:'%d') \t-Waiting for notification...\n", getpid(), getppid());
            fgets(notificator, 100, theNotificationIn);
            printf("(pid:'%d',ppid:'%d') \t-notification received ! '%s'\n", getpid(), getppid(),cleanNewLine(notificator));

            printf("(pid:'%d',ppid:'%d') Sending program name\n", getpid(), getppid());
            fputs(programName, theSenderOut);
            fflush(theSenderOut);

            printf("(pid:'%d',ppid:'%d') \t-Waiting for notification...\n", getpid(), getppid());
            fgets(notificator, 100, theNotificationIn);
            printf("(pid:'%d',ppid:'%d') \t-notification received ! '%s'\n", getpid(), getppid(),cleanNewLine(notificator));

            printf("(pid:'%d',ppid:'%d') Sending program variable\n", getpid(), getppid());
            while (*cursor) {
                fputs(*cursor, theSenderOut);
                fflush(theSenderOut);

                printf("(pid:'%d',ppid:'%d') \t-Waiting for notification...\n", getpid(), getppid());
                fgets(notificator, 100, theNotificationIn);
                printf("(pid:'%d',ppid:'%d') \t-notification received ! '%s'\n", getpid(), getppid(),cleanNewLine(notificator));

                cursor++;
            }
            fflush(theSenderOut);

            printf("(pid:'%d',ppid:'%d') I'm done with %d\n", getpid(), getppid(), wait(NULL));
            break;
        }
    }

    return (0);
}
