/*
 * Kangaroo Punch MultiPlayer Game Server Mark II
 * Copyright (C) 2020-2021  Scott Duensing
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *
 */


// ***TODO*** On DOS, open and close the log on every write so the file gets updated and we still have data on a crash.


#include "log.h"


static FILE        *_log           = NULL;
static uint8_t      _ourHandle     = 0;
static char        *_logBuffer     = NULL;
static uint16_t     _logBufferSize = 0;
static logCallback  _logCallback   = NULL;


void logCallbackSet(logCallback callback) {
	_logCallback = callback;
}


void logClose(void) {
	if (_log && _ourHandle) {
		fclose(_log);
		_ourHandle = 0;
	}
	DEL(_logBuffer);
}


uint8_t logOpen(char *filename, uint8_t append) {
	_log = fopen(filename, append ? "a" : "w");
	if (_log) {
		_ourHandle = 1;
		return 1;
	}
	return 0;
}


void logOpenByHandle(FILE *handle) {
	_log = handle;
}


void logWrite(char *format, ...) {
	va_list  args   = { 0 };
	va_list  args2  = { 0 };
	uint16_t length = 0;

	if (_log) {
		va_start(args, format);
		va_copy(args2, args);

		// Attempt to write into current log buffer.
		length = vsnprintf(_logBuffer, _logBufferSize, format, args);

		// Did it fit?
		if (length >= _logBufferSize) {
			// Nope.  Resize buffer to fit plus a bit more.
			if (_logBuffer) free(_logBuffer);
			_logBufferSize = length + 32;
			_logBuffer     = (char *)malloc(_logBufferSize);
			// Do it again.
			vsnprintf(_logBuffer, _logBufferSize, format, args2);
		}

//#ifdef __linux__
		// Also output to stdout on Linux.
		fprintf(stdout, "%s", _logBuffer);
		fflush(stdout);
//#endif

		if (_logCallback) _logCallback(_logBuffer);

		fprintf(_log, "%s", _logBuffer);
		fflush(_log);

		va_end(args2);
		va_end(args);
	}
}


void logWriteToFileOnly(char *format, ...) {
	va_list args;

	va_start(args, format);

	if (_log) {
		vfprintf(_log, format, args);
		fflush(_log);
	}

	va_end(args);
}
