//
// Asura_Assert.cpp
//
// Created by Simon Watson - 2009/05/11 14:31
// 
// Copyright (C) 2009 Rebellion, All Rights Reserved.
//

#include "Core/Asura.h"

#ifdef ASURA_ASSERT

// This file's header.
#include "Debugging/Asura_Assert.h"

#include "Debugging/Asura_Logfile.h"

///////////////////////////////////

#ifndef ASURA_PLATFORM_ASSERT_OVERRIDES_INDEPENDENT_CODE

static bool g_bIgnoreAllAsserts = false;
static u_int g_uNumAssertsWhilstIgnoreAll = 0;
u_char g_ucAssertIgnoreCounter = 1;

#if defined( ASURA_TOOLS)
static bool g_bLogXML = false;
static char ASSERTION_LOGFILE_XML[ MAX_PATH] = "logfiles\\Assert.xml";
#endif

#ifdef ASURA_MAIN
static bool s_bFirstTimeAssertFired = true;
#endif

///////////////////////////////////

void AsuraAssert_LogClearLog(void)
{
#ifdef ASURA_MAIN
	if (s_bFirstTimeAssertFired)
	{
		s_bFirstTimeAssertFired = false;
		Asura_SimpleLogfileClear(Asura_Platform_Assert_GetLogFileName());
#if defined( ASURA_TOOLS)
		if( true == g_bLogXML)
		{
			Asura_SimpleLogfileClearXML(ASSERTION_LOGFILE_XML);
		}
#endif
	}
#endif
}

#if defined( ASURA_TOOLS)
void AsuraAssert_LogClearLogOnNextAssert( const bool bClear)
{
#ifdef ASURA_MAIN
	s_bFirstTimeAssertFired = bClear;
#endif
}
#endif

#if defined( ASURA_TOOLS)
void AsuraAssert_LogXML( const bool bLogXML)
{
	g_bLogXML = bLogXML;
}
#endif

#if defined( ASURA_TOOLS)
void AsuraAssert_LogXMLFilename( const char* pszFilename)
{
	char* pszBuffer = ASSERTION_LOGFILE_XML;
	u_int uBufferSize = sizeof( ASSERTION_LOGFILE_XML) - 1;
	Asura_PrintfToBfr( pszBuffer, "%s", uBufferSize, true, pszFilename);
}
#endif


void AsuraAssert_SetIgnoreAll(bool bIgnore)
{
	if(bIgnore != g_bIgnoreAllAsserts)
	{
		AsuraAssert_LogClearLog();

		if(bIgnore)
		{
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "****************************************************************\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "*** About to prevent all subsequent asserts from appearing...***\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "****************************************************************\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "\n\n"));

			Asura_OutputToDebugger_Retail(("\n\n"));
			Asura_OutputToDebugger_Retail(("****************************************************************\n"));
			Asura_OutputToDebugger_Retail(("*** About to prevent all subsequent asserts from appearing...***\n"));
			Asura_OutputToDebugger_Retail(("****************************************************************\n"));
			Asura_OutputToDebugger_Retail(("\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\n"));
			Asura_OutputToDebugger_Retail((" \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/ \n\n"));
		}
		else
		{
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "****************************************************************\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "*** ...re-enabling asserts.                                  ***\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "****************************************************************\n"));
			Asura_SimpleLogfileOutput((Asura_Platform_Assert_GetLogFileName(), "\n\n"));

			Asura_OutputToDebugger_Retail((" /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\  /\\ \n"));
			Asura_OutputToDebugger_Retail(("/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\/  \\\n"));
			Asura_OutputToDebugger_Retail(("****************************************************************\n"));
			Asura_OutputToDebugger_Retail(("*** ...re-enabling asserts.                                  ***\n"));
			Asura_OutputToDebugger_Retail(("****************************************************************\n\n"));
		}

		g_bIgnoreAllAsserts = bIgnore;
		Asura_Assertf((bIgnore || (g_uNumAssertsWhilstIgnoreAll == 0)), ("%d asserts fired whilst disabled - see log-file for further details.", g_uNumAssertsWhilstIgnoreAll));
		g_uNumAssertsWhilstIgnoreAll	= 0;
	}
}

bool AsuraAssert_GetIgnoreAll()
{
	return g_bIgnoreAllAsserts;
}

void AsuraAssert_ReEnableAll()
{
	do 
	{
		++g_ucAssertIgnoreCounter;
	} while ( g_ucAssertIgnoreCounter == 0 ); // If we wrap the u_char, don't want to accidentally ignore all asserts
}

bool AsuraAssert_ConsoleCmd_EnableAsserts( bool bHelp )
{
	if ( bHelp )
	{
		return true;
	}
	AsuraAssert_SetIgnoreAll(false);
	AsuraAssert_ReEnableAll();
	return true;
}

void AsuraAssert_RecordAssertHitWhileIgnoringAll()
{
	g_uNumAssertsWhilstIgnoreAll++;
}

#if defined( ASURA_TOOLS)
bool AsuraAssert_ShouldLogToXML()
{
	return g_bLogXML;
}

const char* AsuraAssert_GetXMLLogFilename()
{
	return ASSERTION_LOGFILE_XML;
}
#endif

#endif //ASURA_PLATFORM_ASSERT_OVERRIDES_INDEPENDENT_CODE

#endif // ASURA_ASSERT