
#include "actconfig.h"
#include "actcomdef.h"
#include "actstdlib.h"
#include "acttest.h"
#include "acttestcase.h"
#include "acttestresult.h"

static uint32     __ITestCase_AddRef(ITestCase *pme);
static void     __ITestCase_Delete(ITestCase* pme);
static char*    __ITestCase_name(ITestCase* pme);
static void     __ITestCase_run(ITestCase* pme,ITestResult* pResult);
static int      __ITestCase_countTestCases(ITestCase* pme);

static ITestResult* s_pResult;
static ITestCase* s_pTestCase;


static ITestVtbl g_ITestVtbl =
{
    (PFNTestAddRef) __ITestCase_AddRef,
    (PFNTestDelete) __ITestCase_Delete,
    (PFNTestName) __ITestCase_name,
    (PFNTestRun) __ITestCase_run,
    (PFNCountTestCases)	__ITestCase_countTestCases,
};

ITestCase* ITestCase_Ctor(ITestCase* pme, char *name, PFNSETUP setup, PFNTEARDWON teardown, PFNRUNTEST runTest)
{
	pme->pvt = &g_ITestVtbl;
    pme->m_cRef = 1;
	act_strncpy(pme->name, name, ACT_TEST_NAME_LENGTH);
	pme->setUp = setup;
	pme->tearDown = teardown;
	pme->runTest = runTest;

	return pme;	
}

static uint32     __ITestCase_AddRef(ITestCase *pme)
{
    return ++pme->m_cRef;
}


static void __ITestCase_Delete(ITestCase* pme)
{
    if(--pme->m_cRef == 0)
    {
        act_free(pme);
    }
}

static char* __ITestCase_name(ITestCase* pme)
{
	return pme->name;
}

static void __ITestCase_run(ITestCase* pme,ITestResult* pResult)
{
	ITestResult_startTest(pResult, (ITest*)pme);
	if (pme->setUp) {
		pme->setUp();
	}
	if (pme->runTest) {
		ITestResult* wr =s_pResult;	/*push*/
		ITestCase* ws = s_pTestCase;	/*push*/
		s_pResult = pResult;
		s_pTestCase = pme;
		pme->runTest();
		s_pResult = wr;	/*pop*/
		s_pTestCase = ws;	/*pop*/
	}
	if (pme->tearDown) {
		pme->tearDown();
	}
	ITestResult_endTest(pResult, (ITest*)pme);
}


int __ITestCase_countTestCases(ITestCase* pme)
{
	return 1;
}


void act_addFailure(const char *msg, long line, const char *file)
{	
	ITestResult_addFailure(s_pResult, (ITest*)s_pTestCase, (char*)msg, line, (char*)file);
}
