//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.

#include <windows.h>
#include <tchar.h>
#include "harness.h"

// Global variables
TCHAR *g_szTestMarker = TEXT("---------------------------------------------------------------\r\n");
static TCHAR g_szBuffer[ 1024 ];
DWORD g_dwStartTime, g_dwEndTime;
CRITICAL_SECTION g_cs;
BOOL g_fCritSecInitialized = 0;
HANDLE g_hHeap=NULL;

// This file contains some helper functions related to test-pass / logging.

void CreateLog(const TCHAR* szLogName)
{
	TCHAR szLogFile[MAX_PATH];

	InitHarness();
	g_hHeap = HeapCreate( HEAP_NO_SERIALIZE, 4096, 32768);
	StringCchPrintf(szLogFile, MAX_PATH, TEXT("%s.LOG"), szLogName);
}

void CloseLog()
{
	HeapDestroy( g_hHeap);
	DeinitHarness();
}

HANDLE StartTest( const TCHAR* szText)
{
	PYGTESTDATA pTestData;

	pTestData = (PYGTESTDATA)HeapAlloc( g_hHeap, HEAP_ZERO_MEMORY, sizeof(YGTESTDATA));
	pTestData->bSuccess = TRUE;
	pTestData->szData = szText ? (LPTSTR)HeapAlloc( g_hHeap, 0, (_tcslen( szText)+1)*sizeof(TCHAR)) : NULL;

	if (szText)  
	{
		StringCchCopy(pTestData->szData, _tcslen( szText), szText);
		LogPrint(  TEXT("START: %s\n"), szText);
	}
	return (HANDLE)pTestData;
}

BOOL FinishTest(HANDLE hTest)
{
	BOOL bSuccess;
	const YGTESTDATA* pTestData = (const YGTESTDATA*) hTest;;
	bSuccess = pTestData->bSuccess;

	if (((PYGTESTDATA)hTest)->szData) 
	{
		LogPrint( TEXT("%-5s: %s\n"), bSuccess ? TEXT("PASS") : TEXT("FAIL"), ((PYGTESTDATA)hTest)->szData);
		LogPrint( g_szTestMarker);
		HeapFree( g_hHeap, 0, ((PYGTESTDATA)hTest)->szData);
	}

	HeapFree( g_hHeap, 0, (PYGTESTDATA)hTest);
	return bSuccess;
}

void FailTest( HANDLE hTest)
{
	((PYGTESTDATA)hTest)->bSuccess = FALSE;	
}

BOOL CritSecInitialized()
{
	return g_fCritSecInitialized; 
}

void InitCritSec()
{
	if(!CritSecInitialized())
	{
		InitializeCriticalSection(&g_cs); 
		g_fCritSecInitialized = 1; 
	}
}

HANDLE BeginStep( HANDLE hTest, const TCHAR* szText)  
{
	PYGSTEPDATA pStepData;

	((PYGTESTDATA)hTest)->dwStepsStarted++;
	pStepData = (PYGSTEPDATA)HeapAlloc( g_hHeap, 0, sizeof(YGSTEPDATA));
	pStepData->bSuccess = FALSE;
	pStepData->szData = szText ? (LPTSTR)HeapAlloc( g_hHeap, 0, (_tcslen( szText)+1)*sizeof(TCHAR)) : NULL;
	if (szText)  
	{
 		StringCchCopy(pStepData->szData, _tcslen( szText), szText);
 		LogPrint(  TEXT("BEGIN: %s\n"), szText);
 	}
	return (HANDLE)pStepData;
}

void SkipStep( HANDLE hTest, HANDLE hStep)  
{							   
	((PYGTESTDATA)hTest)->dwStepsSkipped;

	if (((PYGSTEPDATA)hStep)->szData)  
	{ 
		LogPrint( TEXT(" SKIP: %s\n"), ((PYGSTEPDATA)hStep)->szData);
 		HeapFree( g_hHeap, 0, ((PYGSTEPDATA)hStep)->szData);
	}

	HeapFree( g_hHeap, 0, (PYGSTEPDATA)hStep);
	return;
}

void PassStep( HANDLE hStep)  
{
  ((PYGSTEPDATA)hStep)->bSuccess = TRUE;	
}

void EndStep( HANDLE hTest, HANDLE hStep)
{
	BOOL bSuccess;
 
	((PYGTESTDATA)hTest)->dwStepsCompleted++;
	bSuccess = ((PYGSTEPDATA)hStep)->bSuccess;

	if (!bSuccess) FailTest( hTest);

	if (((PYGSTEPDATA)hStep)->szData)  
	{ 
		LogPrint( TEXT("%-5s STEP: %s\n"), bSuccess ? TEXT("PASS") : TEXT("FAIL"), ((PYGSTEPDATA)hStep)->szData);
 		HeapFree( g_hHeap, 0, ((PYGSTEPDATA)hStep)->szData);
	}

	HeapFree( g_hHeap, 0, (PYGSTEPDATA)hStep);
}	

int UTL_Strlen (const char* lpString)
{
	int iLength = 0;
	while ( *lpString != 0 ) 
	{
		iLength += 1;
		lpString += 1;
	}
	return(iLength);
}

void LogDetail( const TCHAR* szFormat, ...)
{
	va_list valist;
 	
	if(!CritSecInitialized())
		InitCritSec();
		
	EnterCriticalSection(& g_cs);
	va_start( valist, szFormat ); 
	StringCchVPrintf( g_szBuffer, 1024, szFormat, valist );
	va_end( valist ); 
	PRINT( TEXT("\t%s\n"), g_szBuffer);

 	LeaveCriticalSection( &g_cs);
}

void LogError( const TCHAR* szText)
{
	DWORD dwErrorCode = GetLastError(); 
	LogDetail( TEXT("%s: Failed with Errorcode %ld"), szText, dwErrorCode);
}
 
void LogPrint(const TCHAR *szFormat, ... )
{
	va_list valist; 

	if(!CritSecInitialized())
		InitCritSec();
	
	EnterCriticalSection( &g_cs);
	va_start( valist, szFormat ); 
	StringCchVPrintf( g_szBuffer, 1024, szFormat, valist );
	va_end( valist );
	PRINT(g_szBuffer);

 	LeaveCriticalSection( &g_cs);
}

void InitHarness()
{
	InitializeCriticalSection( &g_cs);	
	g_dwStartTime = GetTickCount();
}

void DeinitHarness()
{
	DeleteCriticalSection( &g_cs);
	g_dwEndTime = GetTickCount();
}

// Just a stub
BOOL WINAPI DllMain(
	HANDLE	hModule, 
	DWORD	dwReason,
	LPVOID	lpRes
)
{
	return TRUE;
}

