/*
 * @(#)Log.cpp
 *
 * This file is part of webCDwriter - Network CD Writing.
 *
 * Copyright (C) 1999-2003 Jörg P. M. Haeger
 *
 * webCDwriter is free software. See CDWserver.cpp for details.
 */

#include <stdarg.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include "Config.h"
#include "Log.h"

Log::Log() {
	pthread_mutex_init(&mutex, NULL);
	counter = 0;
	outStream = NULL;
}

void Log::debug(const char *tag, const char *format, ...) {
	if (config.getLogLevel() < 9
		&& strstr(config.getDebug(), tag) == NULL)
		return;

	if (outStream == NULL)
		return;

	char str[1024];
	va_list ap;
	va_start(ap, format);
	vsnprintf(str, sizeof str, format, ap);
	va_end(ap);

//	writeLine(9, S.e + tag + " " + str);
	pthread_mutex_lock(&mutex);
	time_t t;
	time(&t);
	struct tm *tm = localtime(&t);
	fprintf(outStream, "%02d%02d%02d T%05d L*",
		tm->tm_hour, tm->tm_min, tm->tm_sec,
		getpid());
	fprintf(outStream, " %s\n", str);
	pthread_mutex_unlock(&mutex);
	fflush(outStream);
}

void Log::debug(const char *tag, String &message) {
	String debug = new String(config.getDebug());
	if (config.getLogLevel() < 9
		&& debug.indexOf(tag) < 0) {
		delete &message;
		return;
	}

	writeLine(9, S.e + tag + " " + message);
	delete &message;
}

void Log::put(int level, const char *message) {
	put(level, S.e + message);
}

void Log::put(int level, String &message) {
	if (level > config.getLogLevel()) {
		delete &message;
		return;
	}
	writeLine(level, message);
}

void Log::put(const char *format, ...) {
	char line[1024];
	va_list ap;
	va_start(ap, format);
	vsnprintf(line, sizeof line, format, ap);
	va_end(ap);

	if (config.getLogLevel() >= 3)
		writeLine(3, S.e + line);
}

void Log::putv(const char *format, ...) {
	char line[1024];
	va_list ap;
	va_start(ap, format);
	vsnprintf(line, sizeof line, format, ap);
	va_end(ap);

	if (config.getLogLevel() >= 4)
		writeLine(4, S.e + line);
}

void Log::restart() {
	if (outStream == NULL || outStream == stdout)
		return;

	File logFile = new File(config.getLogDir(), "log");

	pthread_mutex_lock(&mutex);
	fclose(outStream);
	outStream = fopen(logFile.getPath().getBytes(), "a");
	pthread_mutex_unlock(&mutex);
}

void Log::start(int toStdOut) {
	if (toStdOut)
		outStream = stdout;
	else {
		File logFile = new File(config.getLogDir(), "log");
		outStream = fopen(logFile.getPath().getBytes(), "a");
	}
}

void Log::writeLine(int level, String &line) {
	StringBuffer buf;
	for (int i = 0; i < line.length(); i++)
		if (line.charAt(i) == '\n')
			buf.append("<br>");
		else
			buf.append((char)line.charAt(i));
	delete &line;
	String line2 = new String(buf);

	if (outStream == NULL)
		return;

	pthread_mutex_lock(&mutex);
	if (line2.equals(lastLine))
		counter++;
	else {
		if (counter > 0) {
			fprintf(outStream, "repeated %d times\n", counter);
			counter = 0;
		}

		time_t t;
		time(&t);
		struct tm *tm = localtime(&t);
		fprintf(outStream, "%02d%02d%02d T%05d L%d",
			tm->tm_hour, tm->tm_min, tm->tm_sec,
			getpid(), level);
		fprintf(outStream, " %s\n", line2.getBytes());
	}
	lastLine = line2;
	pthread_mutex_unlock(&mutex);

	fflush(outStream);
}
