#include "utilities/ReferenceCount.h"
#include "unittest/TestSuite.h"

static void * lastZeroCallbackObject;
static unsigned int zeroCallback1Calls, zeroCallback2Calls;

static void zeroCallback1(void * object) {
	lastZeroCallbackObject = object;
	zeroCallback1Calls++;
}

static void zeroCallback2(void * object) {
	lastZeroCallbackObject = object;
	zeroCallback2Calls++;
}

static void testReferenceCounting(void) {
	registerReferenceType(1, zeroCallback1);
	registerReferenceType(2, zeroCallback2);
	
	incrementReferenceCount((void *) 0x1, 1);
	TestCase_assertUIntEqual(zeroCallback1Calls, 0);
	decrementReferenceCount((void *) 0x1);
	TestCase_assertUIntEqual(zeroCallback1Calls, 1);
	TestCase_assertPointerEqual(lastZeroCallbackObject, (void *) 0x1);
	
	incrementReferenceCount((void *) 0x2, 2);
	incrementReferenceCount((void *) 0x2, 2);
	incrementReferenceCount((void *) 0x3, 2);
	incrementReferenceCount((void *) 0x4, 1);
	incrementReferenceCount((void *) 0x4, 1);
	decrementReferenceCount((void *) 0x2);
	decrementReferenceCount((void *) 0x4);
	incrementReferenceCount((void *) 0x4, 1);
	
	TestCase_assertUIntEqual(zeroCallback2Calls, 0);
	decrementReferenceCount((void *) 0x2);
	TestCase_assertUIntEqual(zeroCallback2Calls, 1);
	TestCase_assertPointerEqual(lastZeroCallbackObject, (void *) 0x2);
	decrementReferenceCount((void *) 0x3);
	TestCase_assertUIntEqual(zeroCallback2Calls, 2);
	TestCase_assertPointerEqual(lastZeroCallbackObject, (void *) 0x3);
	
	decrementReferenceCount((void *) 0x4);
	TestCase_assertUIntEqual(zeroCallback1Calls, 1);
	decrementReferenceCount((void *) 0x4);
	TestCase_assertUIntEqual(zeroCallback2Calls, 2);
	TestCase_assertPointerEqual(lastZeroCallbackObject, (void *) 0x4);
}

TEST_SUITE(ReferenceCountTest,
           testReferenceCounting)
