/*

Copyright (C) 2001-2002       A Nourai

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 2
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 included (GNU.txt) 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

#include <string.h>

#include "quakedef.h"
#include "filesystem.h"
#include "logging.h"
#include "utils.h"

static qboolean OnChange_log_dir(cvar_t *var, char *string);

cvar_t		log_dir			= {"log_dir", "", 0, OnChange_log_dir};
cvar_t		log_readable	= {"log_readable", "0"};

#define			LOG_FILENAME_MAXSIZE	(MAX_OSPATH * 2)

static FILE		*logfile;				
static char		logfilename[LOG_FILENAME_MAXSIZE];

static qboolean autologging = false;

qboolean Log_IsLogging(void)
{
	return logfile ? true : false;
}

static char *Log_LogDirectory(void)
{
	static char dir[LOG_FILENAME_MAXSIZE];

	Q_strncpyz(dir, log_dir.string[0] ? va("%s/%s", com_basedir, log_dir.string) : cls.gamedir, sizeof(dir));
	return dir;
}

static void Log_Stop(void)
{
	if (!Log_IsLogging())
		return;

	fclose(logfile);
	logfile = NULL;
}

static qboolean OnChange_log_dir(cvar_t *var, char *string)
{
	if (!string[0])
		return false;

	Util_Process_Filename(string);
	if (!Util_Is_Valid_Filename(string))
	{
		Com_Printf(Util_Invalid_Filename_Msg(var->name));

		return true;
	}

	return false;
}

static void Log_log_f(void)
{
	char *fulllogname;
	FILE *templog;

	switch (Cmd_Argc())
	{
		case 1:
			if (autologging)
				Com_Printf("Auto console logging is in progress\n");
			else if (Log_IsLogging())
				Com_Printf("Logging to %s\n", logfilename);
			else
				Com_Printf("Not logging\n");

			return;
		case 2:
			if (!Q_strcasecmp(Cmd_Argv(1), "stop"))
			{
				if (autologging)
				{
					Log_AutoLogging_StopMatch();
				}
				else
				{
					if (Log_IsLogging())
					{
						Log_Stop();
						Com_Printf("Stopped logging to %s\n", logfilename);
					}
					else
					{
						Com_Printf("Not logging\n");
					}
				}

				return;
			}

			if (autologging)
			{
				Com_Printf("Auto console logging must be stopped first!\n");

				return;
			}

			if (Log_IsLogging())
			{
				Log_Stop();
				Com_Printf("Stopped logging to %s\n", logfilename);
			}

			Q_strncpyz(logfilename, Cmd_Argv(1), sizeof(logfilename) - 4);
			Util_Process_Filename(logfilename);
			if (!Util_Is_Valid_Filename(logfilename))
			{
				Com_Printf(Util_Invalid_Filename_Msg("filename"));

				return;
			}

			COM_ForceExtension (logfilename, ".log");
			fulllogname = va("%s/%s", Log_LogDirectory(), logfilename);
			if (!(templog = fopen (fulllogname, "wb")))
			{
				FS_CreatePath(fulllogname);
				if (!(templog = fopen (fulllogname, "wb")))
				{
					Com_Printf("Error: Couldn't open %s\n", logfilename);

					return;
				}
			}

			Com_Printf("Logging to %s\n", logfilename);
			logfile = templog;

			break;
		default:
			Com_Printf("Usage: %s [filename | stop]\n", Cmd_Argv(0));

			return;
	}
}

void Log_CvarInit(void)
{
	Cvar_SetCurrentGroup(CVAR_GROUP_CONSOLE);
	Cvar_Register (&log_dir);
	Cvar_Register (&log_readable);

	Cvar_ResetCurrentGroup();

	Cmd_AddCommand("log", Log_log_f);
}

void Log_Shutdown(void)
{
	if (Log_IsLogging())	
		Log_Stop();
}

void Log_Write(const char *s)
{
	if (!Log_IsLogging())
		return;

	fprintf(logfile, "%s", s);
}

//=============================================================================
//							AUTO CONSOLE LOGGING
//=============================================================================



static char	auto_matchname[2 * MAX_OSPATH];
static qboolean temp_log_ready = false;
static float auto_starttime;

char *MT_TempDirectory(void);

extern cvar_t match_auto_logconsole, match_auto_minlength;

#define TEMP_LOG_NAME "_!_temp_!_.log"


void Log_AutoLogging_StopMatch(void)
{
	if (!autologging)
		return;

	autologging = false;
	Log_Stop();
	temp_log_ready = true;

	if (match_auto_logconsole.value == 2)
		Log_AutoLogging_SaveMatch();
	else
		Com_Printf ("Auto console logging completed\n");
}


void Log_AutoLogging_CancelMatch(void)
{
	if (!autologging)
		return;

	autologging = false;
	Log_Stop();
	temp_log_ready = true;

	if (match_auto_logconsole.value == 2)
	{
		if (cls.realtime - auto_starttime > match_auto_minlength.value)
			Log_AutoLogging_SaveMatch();
		else
			Com_Printf("Auto console logging cancelled\n");
	}
	else
	{
		Com_Printf ("Auto console logging completed\n");
	}
}


void Log_AutoLogging_StartMatch(char *logname)
{
	char extendedname[MAX_OSPATH * 2], *fullname;
	FILE *templog;

	temp_log_ready = false;

	if (!match_auto_logconsole.value)
		return;

	if (Log_IsLogging())
	{
		if (autologging)
		{
			autologging = false;
			Log_Stop();
		}
		else
		{
			Com_Printf("Auto console logging skipped (already logging)\n");
			return;
		}
	}

	Q_strncpyz(auto_matchname, logname, sizeof(auto_matchname));

	Q_strncpyz (extendedname, TEMP_LOG_NAME, sizeof(extendedname));
	COM_ForceExtension(extendedname, ".log");
	fullname = va("%s/%s", MT_TempDirectory(), extendedname);

	if (!(templog = fopen (fullname, "wb")))
	{
		FS_CreatePath(fullname);
		if (!(templog = fopen (fullname, "wb")))
		{
			Com_Printf("Error: Couldn't open %s\n", fullname);
			return;
		}
	}

	Com_Printf ("Auto console logging commenced\n");

	logfile = templog;
	autologging = true;
	auto_starttime = cls.realtime;
}

qboolean Log_AutoLogging_Status(void)
{
	return temp_log_ready ? 2 : autologging ? 1 : 0;
}

void Log_AutoLogging_SaveMatch(void)
{
	int error, num;
	FILE *f;
	char *dir, *tempname, savedname[2 * MAX_OSPATH], *fullsavedname, *exts[] = {"log", NULL};

	if (!temp_log_ready)
		return;

	temp_log_ready = false;

	dir = Log_LogDirectory();
	tempname = va("%s/%s", MT_TempDirectory(), TEMP_LOG_NAME);

	fullsavedname = va("%s/%s", dir, auto_matchname);
	if ((num = Util_Extend_Filename(fullsavedname, exts)) == -1)
	{
		Com_Printf("Error: no available filenames\n");
		return;
	}
	Q_snprintfz (savedname, sizeof(savedname), "%s_%03i.log", auto_matchname, num);

	fullsavedname = va("%s/%s", dir, savedname);

	if (!(f = fopen(tempname, "rb")))
		return;

	fclose(f);

	if ((error = rename(tempname, fullsavedname)))
	{
		FS_CreatePath(fullsavedname);
		error = rename(tempname, fullsavedname);
	}

	if (!error)
		Com_Printf("Match console log saved to %s\n", savedname);
}

