#include <system_time.hpp>
#include <CppUTest/CommandLineTestRunner.h>

using namespace systime;

TEST_GROUP(SystemTimeTestGroup){};

#define CHECK_HOURS_MONTHS_YEAR_DATE(first, second) \
	CHECK_EQUAL(first.hour, second.hour);           \
	CHECK_EQUAL(first.month, second.month);         \
	CHECK_EQUAL(first.year, second.year);           \
	CHECK_EQUAL(first.date, second.date);

TEST(SystemTimeTestGroup, FirstTest)
{
	std ::string_view name = "";

	name = getMonthText(0);
	CHECK(name == "NaMonth");

	name = getMonthText(1);
	CHECK(name == "Jan");

	name = getMonthText(2);
	CHECK(name == "Feb");

	name = getMonthText(3);
	CHECK(name == "Mar");

	name = getMonthText(4);
	CHECK(name == "Apr");

	name = getMonthText(5);
	CHECK(name == "May");

	name = getMonthText(6);
	CHECK(name == "Jun");

	name = getMonthText(7);
	CHECK(name == "Jul");

	name = getMonthText(8);
	CHECK(name == "Aug");

	name = getMonthText(9);
	CHECK(name == "Sep");

	name = getMonthText(10);
	CHECK(name == "Oct");

	name = getMonthText(11);
	CHECK(name == "Nov");

	name = getMonthText(12);
	CHECK(name == "Dec");
}

TEST(SystemTimeTestGroup, duractionCaclulation)
{
	DateTimeStruct start = {
		.year = 2023, .month = 1, .date = 1, .hour = 0, .minute = 0, .second = 0, .milliSecond = 0};
	DateTimeStruct finish = start;
	finish.milliSecond += 1;

	int64_t ms = systime::getDuration_ms(finish, start);
	CHECK_EQUAL(1, ms);

	finish.second += 1;
	ms = systime::getDuration_ms(finish, start);
	CHECK_EQUAL(1 + 1000, ms);

	finish.minute += 1;
	ms = systime::getDuration_ms(finish, start);
	CHECK_EQUAL(1 + 1000 + 60000, ms);

	finish.hour += 1;
	ms = systime::getDuration_ms(finish, start);
	LONGS_EQUAL(1 + 1000 + 60000 + 3600 * 1000, ms);

	finish.date += 1;
	ms = systime::getDuration_ms(finish, start);
	int64_t answer = 1 + 1000 + 60000 + (3600 * 1000) + (1000 * 3600 * 24);
	LONGS_EQUAL(answer, ms);

	// check the reverse too
	ms = systime::getDuration_ms(start, finish);
	LONGS_EQUAL(-answer, ms);
}


TEST(SystemTimeTestGroup, AdjustTimeTests)
{
	DateTimeStruct time = {
		.year = 2022, .month = 1, .date = 31, .hour = 23, .minute = 59, .second = 58, .milliSecond = 0};

	auto adjusted_time = systime::adjustTime(time, std::chrono::milliseconds(999));
	CHECK(time.second == adjusted_time.second);
	CHECK(time.minute == adjusted_time.minute);
	CHECK(time.hour == adjusted_time.hour);

	adjusted_time = systime::adjustTime(time, std::chrono::milliseconds(1000));
	CHECK((time.second + 1) == adjusted_time.second);
	CHECK(time.minute == adjusted_time.minute);
	CHECK(time.hour == adjusted_time.hour);

	adjusted_time = systime::adjustTime(time, std::chrono::milliseconds(2000));
	CHECK(0 == adjusted_time.second);
	CHECK(0 == adjusted_time.minute);
	CHECK(0 == adjusted_time.hour);
	CHECK(1 == adjusted_time.date);
	CHECK(2 == adjusted_time.month);

	time.month = 12;
	adjusted_time = systime::adjustTime(time, std::chrono::milliseconds(2000));
	CHECK(0 == adjusted_time.second);
	CHECK(0 == adjusted_time.minute);
	CHECK(0 == adjusted_time.hour);
	CHECK(1 == adjusted_time.date);
	CHECK(1 == adjusted_time.month);
	CHECK(2023 == adjusted_time.year);
}
