/**CFile***********************************************************************

  FileName    [main_client.c]

  Synopsis    [Client: Passes an input file that is given as the first argument
               during starting the program. The file contents is passed via a 
	       message queue apporach.
	      ]

  Description [The client assumes that the server has bee started already.
                The server has created the read queue and the client accesses
		this queue.
		In case the SEMAPHORE option is not enabled:
		Client and server are working with two different queues: one for
		passing the information to the server and the second for 
		reading the result that is sent from the server to the client.
		Reading (in the server and in the client) is prtected by a blocking
		read, i.e. the third argument in "msgrcv" is set to "0".
				
		In case the SEMAPHORE option is enabled: 
		There is only one queue used for passing the file to 
		the server. It is the first queue that is created by
		the server.
		Later reading the return-message is done from the same queue. 
		Furthermore, the "msgrcv" system-call is working in the 
		non-blocking mode, i.e. the IPC_NOWAIT flag is given as 
		the third argument whenever the system-call is used.
				
		The name of the client semaphore is SENDKEY and the name
		of the server semaphore is RETURNKEY.
			
		The message queue that is used for communication in the direction
		client -> server is removed by the client after receiving the
		return message.
		]

  Authors     [Ralf Seepold]

******************************************************************************/

#define _FILENAME "main_client.c: "

#include <stdio.h>
#include <errno.h>

#include "def.h"
#include "ao.h"

#ifdef SEMAPHORE
 #include "my_semaphore.h"
#endif

    int main(int argc, char **argv) {
      int queue_id_write;	// id of the queue in that the client writes
      int queue_id_read;	// id of the queue from that the client reads
      long lap;
      myretmesg *receive_data;	//data to be received
      
    	/* 
   	   Begin of declaration of new additional variables
   	   Add here more variables that you use for your individual implementation.
   	   For the reference solution three varable are needed 
   		But you may change this part and tue it toyour solution.
   	*/
   
      int sumoflines;		// total number of lines
   	
   	#ifdef SEMAPHORE
      	MySemaphore *sem_client = NULL;
   		int sem_client_id;			// ID created from name of semaphore
      #endif
   
      
   	/* 
   	   End of declaration of new additional variables
   	*/
      	
      lap = cpuTime();
   	
   /***************************************************
    ***************************************************
    Start your programm after this lines
   ***************************************************
   ***************************************************/
   
   	// check argument vector
      if (argc != 2 ) 
      {
         printf(_FILENAME "Wrong number of arguments!\n");
         printf("usage: main_client <name_of_sourcefile>\n\n");
         exit(-1);
      }
      
   	// create queue for sending
      if ( ( queue_id_write = createQueue(SENDKEY) ) < 0 ) {
         printf(_FILENAME "Error in creating/accessing return queue\n");
         exit(-1);
      }
     
     
      if ( (receive_data = (myretmesg *) malloc (sizeof(myretmesg)) ) == NULL) {
         perror("malloc");
         exit(-1);
      }
      
      sumoflines = 0;
   	
   	#ifdef SEMAPHORE
      if ( (sem_client = malloc (sizeof(MySemaphore))) == NULL ) {
         perror("malloc");
         printf(_FILENAME "Error when reserving memory for semaphore pointer\n");
         exit(-1);
      }
   
      closeRemoveSem(SENDKEY);
      
      if ( (sem_client_id = createSem(sem_client, SENDKEY ) ) == -1) {	// create the semaphore
         printf(_FILENAME "Error reurned when creating semaphore id\n");
         free(sem_client);
         exit(-1);
      }
      #endif
   
      
     	/***************************************************
       Pass input file to server
      ***************************************************/
   
      sumoflines = passfile(argv[1], queue_id_write);
   	
      if (sumoflines == -1) {
         printf(_FILENAME "Error in passfile(): SUM OF LINES IS ODD\n");
      }
      
      if (sumoflines == -2) {
         printf(_FILENAME "Error in passfile(): INVALID LINE NUMBER DETECTED\n");
      }
      
      if (sumoflines == -3) {
         printf(_FILENAME "Error in passfile(): NOT SPECIFIED \n");
      }
   
     	/***************************************************
    	 Prepare reading sum and EOF token in 
   	 the return message queue
     	****************************************************/
   	  
      if (sumoflines >= 0) {
         if ( (queue_id_read = createQueue(RETURNKEY)) < 0) {
            printf(_FILENAME "Error in accessing return queue\n");
            #ifdef SEMAPHORE
            free(sem_client);
            #endif
            exit(-1);
         }
      
      	#ifndef SEMAPHORE      
         if ( (readQueueRet (queue_id_read, receive_data)) < 0 ) {
         	// read the return message from the second message queue
         #endif
         #ifdef SEMAPHORE
         if ( (readQueueRet (queue_id_write, receive_data)) < 0 ) {
         	// read the return message from the first message queue
         	// this is the same queue like to one used for passing the file
         #endif
            printf(_FILENAME "Error in readQueueRet\n");
            #ifdef SEMAPHORE
            free(sem_client);
            #endif
            exit(-1);
         }
      
         if (receive_data->mtype != EOF_TYPE) {	
            printf(_FILENAME "EOF_TYPE not received in first message from server\n");
            #ifdef SEMAPHORE
            free(sem_client);
            #endif
            exit(-1);
         }
         
         if (removeQueue(queue_id_read) != 0)	
            printf(_FILENAME "ERROR: in removeQueue\n");
      }							
   
   /***************************************************
     Do not enter code after this line
   ***************************************************/
      if (sumoflines >= 0) {
         printf(_FILENAME "Sum of lines passed by client: %d\n", sumoflines);
         printf(_FILENAME "Sum of lines received by server: %d\n", receive_data->mlines);
         printf(_FILENAME "Data computed in server: %ld\n", receive_data->msum);
      }
      else
         printf(_FILENAME "ERRORs in execution: %d.\n", sumoflines);
         
      free(receive_data);
   	
      #ifdef SEMAPHORE
   		releaseSem(getSemId(RETURNKEY));
   		closeRemoveSem(SENDKEY);
   		free(sem_client);
   	#endif
   	
      lap = cpuTime() - lap;
      printf("CPU Time CPU: %ld (milisecs.)\n", lap);
      return 0;
   }


