/** SGX

The   sss    gggg x   x   
     s      g      x x    Engine
      sss   g  gg   x
         s  g   g  x x          Copyright 1995-2008.
     ssss    gggg x   x         Steven Goodwin. All Rights Reserved.
    
This version has been released under the GNU Public License v2.0.

Please see the license files for details.

File: src/sgx/core/helpers/trace.cpp

*/

#define  _CRT_SECURE_NO_WARNINGS

#include "sgx/core/types/types.hpp"
#include "sgx/core/stl/stl.hpp"
#include "sgx/core/sgxlib/sgxlib.hpp"
#include "sgx/core/helpers/trace.hpp"

#include <cstdarg>
#include <cstdio>
#include <string>
#include <stdio.h>


CTraceModule::CTraceModule(tINT32 iDefaultLevel/* = SGX_ERR_REPORT_ALL*/)
{
    setTraceLevel(iDefaultLevel);
}

void 
CTraceModule::setTraceLevel(tINT32 iLevel)
{
    m_iTraceLevel = sgxRange(iLevel, SGX_ERR_REPORT_ALL, SGX_ERR_REPORT_NONE);
}

tINT32 
CTraceModule::getTraceLevel(void)
{
    return m_iTraceLevel;
}

void 
CTraceModule::outputTrace(const char *pMessage, ...)
{
    static char buffer[1024];

	if (pMessage == NULL) {
		return;
	}
    va_list va;

	// TODO: This is not thread-safe
    va_start(va, pMessage);
	vsprintf(buffer, pMessage, va);
    va_end(va);

    sgxOutputTraceMessage(buffer);
}

void 
CTraceModule::outputTrace(tINT32 idx, const char *pFile, tMEM_SIZE iLine, const char *pMessage, ...)
{
    static char *pErrLvl[] = {"", "Info", "Msg", "Warn", "Error", "Fatal", ""};
    static char buffer[1024];
    
    if (idx < m_iTraceLevel || pMessage == NULL) {
        return;
    }

    tINT32 lvl = sgxRange(idx, SGX_ERR_INFO, SGX_ERR_FATAL);

    sprintf(buffer, "%s(%d): %s : ", pFile, iLine, pErrLvl[lvl]);
    va_list va;

    va_start(va, pMessage);
    vsprintf((char *)sgxStrchr((tCHAR *)buffer, '\0'), pMessage, va);
    va_end(va);

    sgxOutputTraceMessage(buffer);

    if (idx == SGX_ERR_FATAL) {
        sgxHalt();
    }
}


void 
CTraceModule::outputError(const char *pMessage, ...)
{
    static char buffer[1024];

    va_list va;

    va_start(va, pMessage);
    vsprintf(buffer, pMessage, va);
    va_end(va);

    sgxOutputTraceMessage(buffer);
    sgxHalt();
}

void 
CTraceModule::outputError(const char *pFile, tMEM_SIZE iLine, const char *pMessage, ...)
{
    static char buffer[1024];
    
    sprintf(buffer, "%s(%d): ", pFile, iLine);
    va_list va;

    va_start(va, pMessage);
	vsprintf((char *)sgxStrchr((tCHAR *)buffer, '\0'), pMessage, va);
    va_end(va);

    sgxOutputTraceMessage(buffer);
    sgxHalt();
}
