#include "serialization/SerializationShared.h"
#include "unittest/TestSuite.h"

static void testCheckBitfieldErrors(void) {
	Serialization_bitName bitNames1[] = {
		{"a", 0},
		{"b", 1},
		{"a", 2}
	};
	Serialization_bitName bitNames2[] = {
		{"a", 0},
		{"b", 1},
		{"c", 1}
	};
	Serialization_bitName bitNameJustInRange8 = {"a", 7};
	Serialization_bitName bitNameOutOfRange8 = {"a", 8};
	Serialization_bitName bitNameJustInRange16 = {"a", 15};
	Serialization_bitName bitNameOutOfRange16 = {"a", 16};
	Serialization_bitName bitNameJustInRange32 = {"a", 31};
	Serialization_bitName bitNameOutOfRange32 = {"a", 32};
	Serialization_bitName bitNameJustInRange64 = {"a", 63};
	Serialization_bitName bitNameOutOfRange64 = {"a", 64};
	
	int status = Serialization_checkBitfield8Errors(0, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield8Errors(1, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield8Errors(1, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield8Errors(4, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield8Errors(0, 3, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield8Errors(0, 3, bitNames2);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield8Errors(0, 1, &bitNameJustInRange8);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield8Errors(0, 1, &bitNameOutOfRange8);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_BIT_OUT_OF_RANGE);
	
	status = Serialization_checkBitfield16Errors(0, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield16Errors(1, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield16Errors(1, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield16Errors(4, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield16Errors(0, 3, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield16Errors(0, 3, bitNames2);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield16Errors(0, 1, &bitNameJustInRange16);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield16Errors(0, 1, &bitNameOutOfRange16);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_BIT_OUT_OF_RANGE);
	
	status = Serialization_checkBitfield32Errors(0, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield32Errors(1, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield32Errors(1, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield32Errors(4, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield32Errors(0, 3, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield32Errors(0, 3, bitNames2);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield32Errors(0, 1, &bitNameJustInRange32);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield32Errors(0, 1, &bitNameOutOfRange32);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_BIT_OUT_OF_RANGE);
	
	status = Serialization_checkBitfield64Errors(0, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield64Errors(1, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield64Errors(1, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield64Errors(4, 2, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_UNNAMED_BIT);
	status = Serialization_checkBitfield64Errors(0, 3, bitNames1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield64Errors(0, 3, bitNames2);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_BIT);
	status = Serialization_checkBitfield64Errors(0, 1, &bitNameJustInRange64);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkBitfield64Errors(0, 1, &bitNameOutOfRange64);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_BIT_OUT_OF_RANGE);
}

static void testCheckEnumerationErrors(void) {
	Serialization_enumKeyValue values1[] = {
		{"a", 0},
		{"b", 1},
		{"a", 2}
	};
	Serialization_enumKeyValue values2[] = {
		{"a", 0},
		{"b", 1},
		{"c", 1}
	};
	
	int status = Serialization_checkEnumerationErrors(0, 0, NULL);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_ENUM_NOT_NAMED);
	status = Serialization_checkEnumerationErrors(0, 2, values1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkEnumerationErrors(1, 2, values1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_OK);
	status = Serialization_checkEnumerationErrors(2, 2, values1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_ENUM_NOT_NAMED);
	status = Serialization_checkEnumerationErrors(0, 3, values1);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_ENUM_NAME);
	status = Serialization_checkEnumerationErrors(0, 3, values2);
	TestCase_assertIntEqual(status, SERIALIZATION_ERROR_DUPLICATE_ENUM_VALUE);
}

TEST_SUITE(SerializationSharedTest,
           testCheckBitfieldErrors,
           testCheckEnumerationErrors)
