#include <stdio.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <SDL3/SDL.h>

#include "engine/log.h"

static char* g_month[12] = { "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec" };
static int g_day_in_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
int build_id;
FILE* g_logFile;

extern void PrintToConsole(const char* msg);

void CalculateBuildNumber()
{
	static int start_day = 3;
	static int start_month = 10;
	static int start_year = 2021;

	// Calculating build
	int build = 0, mnum = 0, dnum, ynum, mcnt;
	char mon[4];
	char buf[128];
	strcpy(buf, __DATE__);
	sscanf(buf, "%s %d %d", mon, &dnum, &ynum);
	for (int i = 0; i < 12; i++) {
#ifdef WIN32
		if (stricmp(g_month[i], mon) == 0) {
#else
		if (strcasecmp(g_month[i], mon) == 0) {
#endif // WIN32
			mnum = i;
			break;
		}
	}

	build_id = (ynum - start_year) * 365 + dnum - start_day;

	for (int i = 0; i < mnum; ++i)
		build_id += g_day_in_month[i];

	for (int i = 0; i < start_month - 1; ++i)
		build_id -= g_day_in_month[i];
}

void Logger::Open()
{
	CalculateBuildNumber();

#if 0//def WIN32
	char UserName[256];
	DWORD dwUserName = 256;

	if (!GetUserNameA(UserName, &dwUserName))
		strcpy(UserName, "unnamed");

	char logfilename[256];
	sprintf(logfilename, "engine_%s.log", UserName);
#else
	char logfilename[256];
	sprintf(logfilename, "engine.log");
#endif

	g_logFile = fopen(logfilename, "w");

	Msg("'%s' build %d, %s", "engine", build_id, __DATE__);
}

void Logger::Close()
{
	if (g_logFile) {
		fclose(g_logFile);
		g_logFile = nullptr;
	}
}

void Logger::Msg(const char* fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	MsgArg(fmt, args);
	va_end(args);
}

void Logger::MsgArg(const char* fmt, va_list args)
{
	char buffer[2048];

	int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
	assert(len >= 0);
	assert(len < 2048);
	SDL_assert_always(len >= 0);
	SDL_assert_always(len < 2048);

	//if (len >= sizeof(buffer))
	//	len = sizeof(buffer) - 1;

	//if (buffer[len] != '\n' && len < sizeof(buffer) - 1)
	//{
	//	buffer[len++] = '\n';
	//	buffer[len] = '\0';
	//}

	len = strlen(buffer);

	if (buffer[len - 1] != '\n')
	{
		buffer[len++] = '\n';
		buffer[len] = '\0';
	}
	
	//time_t t = time(0);
	//struct tm* ti = localtime(&t);

	//char timestr[256];
	//sprintf(timestr, "%s", asctime(ti));
	//timestr[strlen(timestr) - 1] = '\0';

	//sprintf(buffer2, "[%s] %s", timestr, buffer);

	PrintToConsole(buffer);

	if (g_logFile)
	{
		fwrite(buffer, sizeof(char), len, g_logFile);
		fflush(g_logFile);
	}

#ifdef WIN32
	//OutputDebugStringA(buffer);
	fwrite(buffer, sizeof(char), len, stdout);
#else
	fwrite(buffer, sizeof(char), len, stdout);
#endif
}

void Msg(const char* fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	Logger::MsgArg(fmt, args);
	va_end(args);
}
