//
//logger.c
//
//Provides functions for logging.
//
//
//-UserX 2001/11/02
//todo: better detection of logfilename changes

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "base/logger.h"
#include "base/mem.h"
#include "base/str.h"
#include "file/file.h"


int atexiton = 0;
int verbosity = LOG_NORMAL;

char defaultlogfilename[] = DEFAULT_LOGFILE;
char *logfilename = NULL;

FILE *logfile = NULL;
FileHandle *logfile2 = NULL;

int logpossible = 1;

int quietconsole = 0;

int logsafemode = 0;

//closes the log file
void exitLog(void){
	if(logfile != NULL) {
		fclose(logfile);
		logfile = NULL;
	}
	if(logfile2 != NULL) {
		fileClose(logfile2);
		logfile2 = NULL;
	}
}

//opens the log file and adds a function to atexit (if it has not done so yet)
//if the log file is already it will close it then open it again.
void initLog(void){
	if(!atexiton) {
		atexit(exitLog);
		atexiton = -1;
	}
	if(logfile != NULL || logfile2 != NULL) {
		exitLog();
	}
	if(logpossible == 0) {
		return;
	}
	if(logsafemode == 0 && filesysactive != 0) {
		if(isStringBlank(logfilename)) {
			logfile2 = fileOpen(defaultlogfilename, "a");
		} else {
			logfile2 = fileOpen(logfilename, "a");
		}
	}
	if(logfile2 == NULL) {
		if(isStringBlank(logfilename)) {
			if(defaultlogfilename[0] == '@') {
				logfile = fopen(defaultlogfilename + 1, "a");
			} else {
				logfile = fopen(defaultlogfilename, "a");
			}
		} else {
			if(logfilename[0] == '@') {
				logfile = fopen(logfilename + 1, "a");
			} else {
				logfile = fopen(logfilename, "a");
			}
		}
	}
	if(logfile == NULL && logfile2 == NULL) {
		logpossible = 0;
		LOGERROR("Unable to open logfile!"); //todo: include the actual logfile name
		return;
	}
	logmsgraw("----------------------------------------------------------------------");
	LOGERROR(stringJoin("Logging at verbosity:", intToString(verbosity)));
	

}

void setVerbosity(int v){
	verbosity = v;
}


//sets the filename to log to.
//no validation of the file name is performed.
void setLogFileName(char *filename) {
	logpossible = 1;
	stringFree(logfilename);
	if(filename == NULL || strlen(filename) == 0) {
		logfilename = NULL;
	} else {
		logfilename = stringCopy(filename);
	}

	if(logfile != NULL) {//if there is a log file open close it and reopen it
		initLog();
	}
}

void logWriteLine(char *message) {
	if(message == NULL) {
		return;
	}
	if(logfile2 != NULL && logsafemode == 0) {
		fileWriteStringKeep(logfile2, message);
		fileWriteStringKeep(logfile2, "\n");
		fileFlush(logfile2);
	}
	if(logfile != NULL) {
		fprintf(logfile, "%s\n", message);
		fflush(logfile);
	}
	if(!quietconsole) {
		printf("%s\n", message);
	}
}

//log a msg without any timestamping or verbosity checking
void logmsgraw(char *message) {
	if(message == NULL) {
		logmsgraw("NULL passed to logmsgraw.");
		return;
	}

	if(logfile2 == NULL && logsafemode == 0 && filesysactive != 0) {
		/*attempt to log with FileHandle based files*/
		initLog();
	} 
	if(logfile2 == NULL && logfile == NULL) {
		/*otherwise attempt to log FILE base files*/
		initLog();
	}


	logWriteLine(message);			
}

//will only write to the log file if it is already open
void logmsgsafe(char *message) {
	logWriteLine(message);
}


//log a message with a timestamp.
void logmsg(int verblevel, char *message){
	char *msg;

	if(message == NULL) {
		logmsg(1, "NULL passed to logmsg.");
		return;
	}

	if(verblevel > verbosity) { //return if the verbosity of the message is too high to log.
		return;
	}

	msg = stringAppend3("[", stringDateTime(time(NULL)), "]:");
	msg = stringAppend(msg, message);

	logmsgraw(msg);

	stringFree(msg);
}

//logmsg except message is released via stringFree
void logstring(int verblevel, char *message) {
	logmsg(verblevel, message);
	stringFree(message);
}

