#include "stdafx.h"

#ifdef _DEBUG

#include "DebugTrace.h"
#include <malloc.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <Windows.h>
#include <DbgHelp.h>

// static volatile long s_debugLineCount;



volatile long *allocateLineCount()
{
	static volatile long *lineCount;

	lineCount = (long*)_aligned_malloc(sizeof(long), 32);
	*lineCount = 0;
	return lineCount;
}

void printStack()
{
	unsigned int   i;
	void         * stack[ 100 ];
	unsigned short frames;
	SYMBOL_INFO  * symbol;
	HANDLE         process;
	char buffer[500]{};
	int bufferRemaining = 500;
	int usedBuffer;
	char *output = buffer;

	process = GetCurrentProcess();

	SymInitialize( process, NULL, TRUE );

	frames               = CaptureStackBackTrace( 1, 15, stack, NULL );
	symbol               = ( SYMBOL_INFO * )calloc( sizeof( SYMBOL_INFO ) + 256 * sizeof( char ), 1 );
	symbol->MaxNameLen   = 255;
	symbol->SizeOfStruct = sizeof( SYMBOL_INFO );

	
	for( i = 0; i < frames; i++ )
	{
		SymFromAddr( process, ( DWORD64 )( stack[ i ] ), 0, symbol );

		usedBuffer = _snprintf_s(output, bufferRemaining, bufferRemaining, "%i: %s - 0x%I64X\n", frames - i - 1, symbol->Name, symbol->Address );
		bufferRemaining -= usedBuffer;
		output += usedBuffer;
	}

	debugTraceVars("STACK %s", buffer);

	free( symbol );
}

void debugTraceStr(const std::wstringstream& item)
{
	static volatile long *lineCount = allocateLineCount(); 
	FILETIME timestamp;
	GetSystemTimeAsFileTime(&timestamp);

	
	long currentLine = InterlockedIncrement(lineCount);
	std::wstringstream debug;
	debug << L"PY>" << std::setfill(L'0') << std::setw(5) << ::GetCurrentThreadId() 
				<< L" " << std::setw(5) << std::setfill(L' ') << currentLine 
				<< L" " << std::setw(8) << std::setfill(L' ') << timestamp.dwLowDateTime 
				<< L" " << item.str();

	OutputDebugString(debug.str().c_str());
}

void debugTraceVars(const char *format, ...)
{
	va_list args;
	va_start( args, format );
	char buffer[500];
	vsprintf_s<500>(buffer, format, args); 
	std::wstringstream result;
	result << buffer;
	debugTraceStr(result);
}


#endif 