#include <string.h>
#include <sc_unittest.h>
#include <sc_mmgr.h>
#include <sc_thread.h>


static void UT_SC_Thread_start(void);
static void UT_SC_Thread_start_null(void);
static void UT_SC_Mutex_lock(void);

static void UT_SC_Thread_testThreadMethod(void* data);

static int     UT_SC_Thread_runThreadCount;
static void*   UT_SC_Thread_runThreadLastData;
static mutex_t UT_SC_Mutex_mutex;

void UT_regist_sc_thread(void)
{
	SC_Unittest_add("SC_Thread_start"				, UT_SC_Thread_start);
	SC_Unittest_add("SC_Thread_start_null"			, UT_SC_Thread_start_null);
	SC_Unittest_add("SC_Mutex_lock"					, UT_SC_Mutex_lock);

}



static
void UT_SC_Thread_testThreadMethod(void* data)
{
	UT_SC_Thread_runThreadCount++;
	UT_SC_Thread_runThreadLastData = data;
}

static
void UT_SC_Mutex_testThreadMethod1(void* data)
{
	int     i;
	SC_Mutex_lock(&UT_SC_Mutex_mutex);
	UT_SC_Thread_runThreadLastData = data;
	for (i = 0; i < 100; i++)
	{
		SC_sleep(1);
		SC_assertNumber(i, UT_SC_Thread_runThreadCount);
		UT_SC_Thread_runThreadCount++;
	}
	SC_Mutex_unlock(&UT_SC_Mutex_mutex);
}

static
void UT_SC_Mutex_testThreadMethod2(void* data)
{
	int     i;
	SC_Mutex_lock(&UT_SC_Mutex_mutex);
	UT_SC_Thread_runThreadLastData = data;
	for (i = 0; i < 100; i++)
	{
		SC_sleep(1);
		SC_assertNumber((i + 100), UT_SC_Thread_runThreadCount);
		UT_SC_Thread_runThreadCount++;
	}
	SC_Mutex_unlock(&UT_SC_Mutex_mutex);
}


static
void UT_SC_Thread_start(void)
{
	UT_SC_Thread_runThreadCount    = 0;
	UT_SC_Thread_runThreadLastData = NULL;
	SC_Thread* thread = SC_Thread_new(
			UT_SC_Thread_testThreadMethod, "ABC", 4);

	thread->start(thread);
	thread->join(thread);
	SC_assertNumber(1, UT_SC_Thread_runThreadCount);
	SC_assertString("ABC", UT_SC_Thread_runThreadLastData);
	SC_Thread_delete(thread);
}

static
void UT_SC_Thread_start_null(void)
{
	UT_SC_Thread_runThreadCount    = 0;
	UT_SC_Thread_runThreadLastData = NULL;
	SC_Thread* thread = SC_Thread_new(
			UT_SC_Thread_testThreadMethod, NULL, 0);

	thread->start(thread);
	thread->join(thread);
	SC_assertNumber(1, UT_SC_Thread_runThreadCount);
	SC_assert(NULL == UT_SC_Thread_runThreadLastData);
	SC_Thread_delete(thread);
}

static
void UT_SC_Mutex_lock(void)
{
	UT_SC_Thread_runThreadCount    = 0;
	UT_SC_Thread_runThreadLastData = NULL;
	SC_Thread* thread1 = SC_Thread_new(
			UT_SC_Mutex_testThreadMethod1, "ABC", 4);
	SC_Thread* thread2 = SC_Thread_new(
			UT_SC_Mutex_testThreadMethod2, "XYZ", 4);

	SC_Mutex_init(&UT_SC_Mutex_mutex);

	thread1->start(thread1);
	SC_sleep(10);
	thread2->start(thread2);
	thread1->join(thread1);
	thread2->join(thread2);

	SC_Thread_delete(thread1);
	SC_Thread_delete(thread2);

	SC_Mutex_destroy(&UT_SC_Mutex_mutex);
}
