/**Chris Jarrett
 * Comp289 - Lab6
 * Usage: msgLogger <log file>
 */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/neutrino.h>
#include <string.h>
#include "msg.h"
#include <process.h>

int processMessage(int rcvid, MESSAGE *m, char **toWrite);

int main(int argc, char *argv[]) {
	int chid;
	int clientID;
	MESSAGE *msg;
	FILE *pidFile;
	FILE *logFile;
	int status;
	msg = malloc(sizeof(MESSAGE));
	char *toWrite = malloc(26+MSG_SIZE+(sizeof(int)*3)+10);

	//not the right number of args
	if(argc != 2) {
		printf("Incorrect arguments. Should be: \"%s <log name>\".", argv[0]);
		return EXIT_FAILURE;
	}

	//get pid file to make from input
	char *loggerPidName;
	loggerPidName = (char*)malloc(strlen(argv[0]) + 5);
	strcpy(loggerPidName, argv[0]);
	strcat(loggerPidName, ".pid");

	//create channel and write the pid file
	pidFile = fopen(loggerPidName, "w+");
	chid = ChannelCreate(0);
	fprintf(pidFile, "0 %d %d", getpid(), chid);
	fflush(pidFile);
	fclose(pidFile);

	//open the log file to append
	logFile = fopen(argv[1], "a+");

	while(1) {
		//receive message
		clientID = MsgReceive(chid, msg, sizeof(MESSAGE), NULL);

		//process the message
		status = processMessage(clientID, msg, &toWrite);

		//reply
		MsgReply(clientID, status, NULL, 0);

		//write data and flush log file to disk
		fprintf(logFile, "%s\n", toWrite);
		fflush(logFile);

		//if iy's the end, cleanup and exit
		if(status == MSG_END) {
			remove(loggerPidName);
			free(loggerPidName);
			fclose(logFile);
			return 1;
		}
	}
}

/**
 * function to handle messages
 */
int processMessage(int rcvid, MESSAGE *m, char **toWrite) {
	struct _msg_info* info;
	info = malloc(sizeof(struct _msg_info));

	//get the time
	time_t theTime = time(NULL);
	char *message = malloc(26+MSG_SIZE+(sizeof(int)*3)+10);
	char timeString[26];
	ctime_r(&theTime, timeString);
	timeString[24] = ':';

	char* nd = (char*)malloc(10);
	char* pid = (char*)malloc(10);
	char* chid = (char*)malloc(10);

	switch(m->m_hdr) {
		case MSG_DATA:
			//copy the time over
			strcpy(message, timeString);

			//get the message info
			MsgInfo(rcvid, info);

			//put the strings needed in the pointer to be written
			sprintf(nd, " %d", info->nd);
			sprintf(pid, "%d", info->pid);
			sprintf(chid, "%d", info->chid);

			strcat(message, nd);
			strcat(message, "/");
			strcat(message, pid);
			strcat(message, "/");
			strcat(message, chid);
			strcat(message, " sent: ");
			strcat(message, m->m_data);
			*toWrite = message;
			return MSG_OK;

		case MSG_END:
			strcpy(message, timeString);
			strcat(message, " Shutdown message received");
			*toWrite = message;
			return MSG_END;

		default:
			//copy the time over
			strcpy(message, timeString);

			//get the message info
			MsgInfo(rcvid, info);

			//put the strings needed in the pointer to be written
			sprintf(nd, " %d", info->nd);
			sprintf(pid, "%d", info->pid);
			sprintf(chid, "%d", info->chid);

			strcat(message, nd);
			strcat(message, "/");
			strcat(message, pid);
			strcat(message, "/");
			strcat(message, chid);

			strcat(message, " received invalid data");
			*toWrite = message;
			return MSG_INVALID;
	}
}

