/**
 * Handle Decorator pattern by OS signal, or another IPC
 * e.g Integer in a shm that specifie how to behave
 * 
 * @param argc
 * @param argv
 * @return
 */
#include <stdio.h>
#include <stdlib.h>

#include <errno.h>

#include <string.h>

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>

#include <signal.h>

#include <time.h>

#include "configuration.h"

#define MAX_FILE_SIZE 1000000
#define LOG_PATTERN   "optim-eisti-%03u.log"

//4 : Interrupted sys call, allow me to permit to control logger daemon by signal
#define handle(a,mess,errorcode)    \
    if(a && errno != 4){             \
        perror(mess);                \
        printf("ERRNO : %d\n",errno);\
        return errorcode;            \
    }

int   lastFile;
char *logfile= "optim-eisti-000.log";
void(*logHandler)(char *);

int activated = TRUE;

FILE *log_file;

void basicLog(char * logmessage);
void dateLog (char * logmessage);

void checkLogSize();
void turnFile();

void killLoggerProcess(int signum);
void makeDateLogger(int signum);

int main(int argc, char *argv[])
{
    key_t queue_id;
    key_t logger_shm_id;

    int msg_id;
    int shm_id;
    int control;

    int *shmHolder;

    MessageBuffer theMsg;

    //Signal handler
    signal(SIGUSR1,killLoggerProcess);
    signal(SIGUSR2,makeDateLogger);

    //delete old log files
    system("sudo rm optim-eisti*.log");

    printf("Démarrage du démon de log... (%d)\n",getpid());

    queue_id = ftok(SECRETS_FILE,LOGGER_QUEUE_ID);
    logger_shm_id = ftok(SECRETS_FILE,LOGGER_PID);

    msg_id = msgget(queue_id, IPC_CREAT);
        handle(msg_id < 0,"LOGGER -> msgget: ",-1);

    theMsg.mtype	= 1;
    strcpy(theMsg.mtext, "");

    logHandler = basicLog;

    printf("Démon de log prêt.\n");

    //Attach pid
	shm_id = shmget(logger_shm_id,sizeof(pid_t),IPC_CREAT);
        handle(shm_id < 0,"LOGGER -> shmget: ",-1);

    shmHolder = (int *)shmat(shm_id,NULL,0);

    *shmHolder = getpid();

    shmdt(shmHolder);

	printf("logfile : %s\n",logfile);
	lastFile = 0;
    do
    {
		control	= msgrcv(
					msg_id,                     // message queue
					(MessageBuffer *)&theMsg,   // message structure
					MAX_STRING_INPUT,           // message size
					(long)0,                    // read the first message
					NO_FLAG);                   // wait
				handle(control < 0,"LOGGER -> msgrcv: ",-2);

		checkLogSize();

		if(strcmp(theMsg.mtext,""))
			logHandler(theMsg.mtext);

    }while( activated );

    printf("Logger successfully terminated\n");

    return (EXIT_SUCCESS);
}

void basicLog(char * logmessage)
{
	log_file = fopen(logfile,"a");
	fprintf(log_file,"%s\n",logmessage);
	fclose(log_file);
}

void dateLog(char * logmessage)
{
	static char buffer[20];
	memset(buffer,0,sizeof(buffer));

	time_t current = time(NULL);
	strftime(buffer,sizeof(buffer),"%Y-%m-%d %H-%m-%S",localtime(&current));

	log_file = fopen(logfile,"a");
	fprintf(log_file,"{%s} %s\n",buffer,logmessage);
	fclose(log_file);
}

void checkLogSize() {
	FILE* file = fopen(logfile,"a");
	fseek(file,0L,SEEK_END);
	if( ftell(file) > MAX_FILE_SIZE ) {
		printf("\nMax size reached : %ld > %d\n",ftell(file),MAX_FILE_SIZE);
		printf("starting turn file process...\n");
		turnFile();
		printf("file turned success!\n");
	}
	fclose(file);
}

void turnFile() {
	int i;
	char oldfile[100];
	char newfile[100];
	char command[400];
	for(i=lastFile;i>=0;i--){
		sprintf(oldfile,LOG_PATTERN,i);
		sprintf(newfile,LOG_PATTERN,(i+1));
		sprintf(command,"mv %s %s",oldfile,newfile);
		system(command);
	}
	lastFile++;
}

void killLoggerProcess(int signum)
{
	activated = FALSE;
    log_file = NULL;
}

void makeDateLogger(int signum)
{
	logHandler = dateLog;
}
