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


#define UT_SC_ITERATOR_DUMMY_MAX (10)
static SC_Iterator_Entry* UT_SC_dummyEntry = NULL;
static const char* UT_SC_dummyDatas[UT_SC_ITERATOR_DUMMY_MAX] = {
	"value1", "value2", "value3", "value4", "value5",
	"value6", "value7", "value8", "value9", "value10"
};

static void UT_SC_iterator_init(void);
static void UT_SC_iterator_cleanup(void);

static void UT_SC_iterator_new(void);
static void UT_SC_iterator_delete(void);
static void UT_SC_iterator_hasNext(void);
static void UT_SC_iterator_next(void);
static void UT_SC_iterator_next_noData(void);


void UT_regist_sc_iterator(void)
{
	/* UTのための初期化		*/
	SC_Unittest_add("OTHER"						, UT_SC_iterator_init);

	/* 単体試験	関数登録	*/
	SC_Unittest_add("SC_iterator_new"              , UT_SC_iterator_new);
	SC_Unittest_add("SC_iterator_delete"           , UT_SC_iterator_delete);
	SC_Unittest_add("SC_iterator_hasNext"          , UT_SC_iterator_hasNext);
	SC_Unittest_add("SC_iterator_next"             , UT_SC_iterator_next);
	SC_Unittest_add("SC_iterator_next_noData"      , UT_SC_iterator_next_noData);

	/* UTのための後処理		*/
	SC_Unittest_add("OTHER"						, UT_SC_iterator_cleanup);
}


static
void UT_SC_iterator_init(void)
{
	int                i;
	SC_Iterator_Entry* entry;
	size_t             size;
	size             = sizeof(SC_Iterator_Entry) * UT_SC_ITERATOR_DUMMY_MAX;
	UT_SC_dummyEntry = (SC_Iterator_Entry*) malloc(size);
	entry            = UT_SC_dummyEntry;

	for (i = 0; i < UT_SC_ITERATOR_DUMMY_MAX; i++)
	{
		if (i == (UT_SC_ITERATOR_DUMMY_MAX - 1))
		{
			entry->next = NULL;
		}
		else
		{
			entry->next  = (entry + 1);
		}
		entry->value = UT_SC_dummyDatas[i];
		entry->size  = strlen(UT_SC_dummyDatas[i]) + 1;
		entry        = entry->next;
	}
}

static
void UT_SC_iterator_cleanup(void)
{
	free(UT_SC_dummyEntry);
}

static
void UT_SC_iterator_new(void)
{
	SC_Iterator* ite = SC_Iterator_new(UT_SC_dummyEntry);
	SC_Iterator_delete(ite);
}

static
void UT_SC_iterator_delete(void)
{
	SC_Iterator* ite = SC_Iterator_new(UT_SC_dummyEntry);
	SC_Iterator_delete(ite);
}

static
void UT_SC_iterator_hasNext(void)
{
	int index = 0;
	SC_Iterator* ite = SC_Iterator_new(UT_SC_dummyEntry);
	while (ite->hasNext(ite))
	{
		SC_assertString(UT_SC_dummyDatas[index], ite->nextStr(ite));
		index++;
	}
	SC_assertNumber(UT_SC_ITERATOR_DUMMY_MAX, index);
	SC_Iterator_delete(ite);
}

static
void UT_SC_iterator_next(void)
{
	int    index = 0;
	size_t size;
	const void* data;
	SC_Iterator* ite = SC_Iterator_new(UT_SC_dummyEntry);
	while (ite->hasNext(ite))
	{
		data = ite->next(ite, &size);
		SC_assert(size != 0);
		SC_assertMemory(UT_SC_dummyDatas[index], data, size);
		index++;
	}
	SC_assertNumber(UT_SC_ITERATOR_DUMMY_MAX, index);
	SC_Iterator_delete(ite);
}

static
void UT_SC_iterator_next_noData(void)
{
	int    index = 0;
	size_t size;
	const void* data;
	SC_Iterator* ite = SC_Iterator_new(UT_SC_dummyEntry);
	while (ite->hasNext(ite))
	{
		data = ite->next(ite, &size);
		SC_assert(size != 0);
		SC_assertMemory(UT_SC_dummyDatas[index], data, size);
		index++;
	}
	SC_assertNumber(UT_SC_ITERATOR_DUMMY_MAX, index);

	/* 既にデータがない状態で取得	*/
	data = ite->next(ite, &size);
	SC_assert(data == NULL);

	SC_Iterator_delete(ite);
}

