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


static void UT_SC_list_new(void);
static void UT_SC_list_delete(void);
static void UT_SC_list_add(void);
static void UT_SC_list_add_insert(void);
static void UT_SC_list_add_insert5(void);
static void UT_SC_list_add_invalidIndex(void);
static void UT_SC_list_add_end(void);
static void UT_SC_list_addStr(void);
static void UT_SC_list_get(void);
static void UT_SC_list_get_invalidIndex(void);
static void UT_SC_list_remove(void);
static void UT_SC_list_remove_noEntry(void);
static void UT_SC_list_clear(void);


#define UT_SC_LIST_DATA_SIZE (10)
static const char* UT_SC_LIST_DATA[UT_SC_LIST_DATA_SIZE] = {
	"value1", "value2", "value3", "value4", "value5",
	"value6", "value7", "value8", "value9", "value10"
};

void UT_regist_sc_list(void)
{
	SC_Unittest_add("SC_list_new"         , UT_SC_list_new);
	SC_Unittest_add("SC_list_delete"      , UT_SC_list_delete);
	SC_Unittest_add("SC_list_add"         , UT_SC_list_add);
	SC_Unittest_add("SC_list_add_insert"  , UT_SC_list_add_insert);
	SC_Unittest_add("SC_list_add_insert5" , UT_SC_list_add_insert5);
	SC_Unittest_add("SC_list_add_invalidIndex", UT_SC_list_add_invalidIndex);
	SC_Unittest_add("SC_list_add_end"     , UT_SC_list_add_end);
	SC_Unittest_add("SC_list_addStr"      , UT_SC_list_addStr);
	SC_Unittest_add("SC_list_get"         , UT_SC_list_get);
	SC_Unittest_add("SC_list_get_invalidIndex", UT_SC_list_get_invalidIndex);
	SC_Unittest_add("SC_list_remove"      , UT_SC_list_remove);
	SC_Unittest_add("SC_list_remove_noEntry", UT_SC_list_remove_noEntry);
	SC_Unittest_add("SC_list_clear"       , UT_SC_list_clear);

}


static
void UT_SC_list_new(void)
{
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);
	SC_List_delete(list);
}

static
void UT_SC_list_delete(void)
{
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);
	SC_List_delete(list);
}

static
void UT_SC_list_add(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	SC_assertNumber(UT_SC_LIST_DATA_SIZE, list->size);
	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i, NULL));
	}

	SC_List_delete(list);
}

static
void UT_SC_list_add_insert(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	list->add(list, 0, "XYZ", strlen("XYZ") + 1);
	SC_assertString("XYZ", list->get(list, 0, NULL));
	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i + 1, NULL));
	}

	SC_List_delete(list);
}

static
void UT_SC_list_add_insert5(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	list->add(list, 5, "XYZ", strlen("XYZ") + 1);
	SC_assertString("XYZ", list->get(list, 5, NULL));
	for (i = 0; i < 5; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i, NULL));
	}
	for (i = 6; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i + 1, NULL));
	}

	SC_List_delete(list);
}

static
void UT_SC_list_add_invalidIndex(void)
{
	SC_List* list = SC_List_new();
	list->add(list, 2, "XYZ", strlen("XYZ") + 1);
	SC_List_delete(list);
}

static
void UT_SC_list_add_end(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	SC_assertNumber(UT_SC_LIST_DATA_SIZE, list->size);
	list->add(list, -1, "XYZ", strlen("XYZ") + 1);
	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i, NULL));
	}
	SC_assertString("XYZ", list->get(list, list->size - 1, NULL));

	SC_List_delete(list);
}

static
void UT_SC_list_addStr(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->addStr(list, i, UT_SC_LIST_DATA[i]);
	}
	SC_assertNumber(UT_SC_LIST_DATA_SIZE, list->size);
	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->getStr(list, i));
	}

	SC_List_delete(list);
}

static
void UT_SC_list_get(void)
{
	int i;
	size_t size;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->addStr(list, i, UT_SC_LIST_DATA[i]);
	}
	SC_assertNumber(UT_SC_LIST_DATA_SIZE, list->size);
	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i, &size));
		SC_assertNumber(strlen(UT_SC_LIST_DATA[i]) + 1, size);
	}

	SC_List_delete(list);
}

static
void UT_SC_list_get_invalidIndex(void)
{
	const char* ret;
	SC_List* list = SC_List_new();
	list->addStr(list, 0, "XYZ");
	ret = list->getStr(list, 2);
	SC_assert(ret == NULL);
	SC_List_delete(list);
}

static
void UT_SC_list_remove(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	list->remove(list, 5);
	SC_assertNumber(UT_SC_LIST_DATA_SIZE - 1, list->size);
	for (i = 0; i < 5; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i], list->get(list, i, NULL));
	}
	for (i = 5; i < UT_SC_LIST_DATA_SIZE - 1; i++)
	{
		SC_assertString(UT_SC_LIST_DATA[i + 1], list->get(list, i, NULL));
	}

	SC_List_delete(list);
}

static
void UT_SC_list_remove_noEntry(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	list->remove(list, 11);
	SC_assertNumber(UT_SC_LIST_DATA_SIZE, list->size);
	SC_List_delete(list);
}

static
void UT_SC_list_clear(void)
{
	int i;
	SC_List* list = SC_List_new();
	SC_assert(list != NULL);

	for (i = 0; i < UT_SC_LIST_DATA_SIZE; i++)
	{
		list->add(list, i,
				UT_SC_LIST_DATA[i],
				strlen(UT_SC_LIST_DATA[i]) + 1);
	}
	list->clear(list);
	SC_assertNumber(0, list->size);
	SC_List_delete(list);
}

