#include "catch.hpp"
#include "Date.hh"
#include <cstring>

using namespace openmsx;

static void test(time_t t, const char* s)
{
	REQUIRE(strlen(s) >= 24); // precondition
	CHECK(Date::fromString(s) == t);
	CHECK(Date::toString(t)   == s);
}

TEST_CASE("Date")
{
	putenv(const_cast<char*>("TZ=UTC")); tzset();
	test(         0, "Thu Jan 01 00:00:00 1970");
	test(         1, "Thu Jan 01 00:00:01 1970");
	test(        60, "Thu Jan 01 00:01:00 1970");
	test(      3600, "Thu Jan 01 01:00:00 1970");
	test(1318850077, "Mon Oct 17 11:14:37 2011");
	test(1403092862, "Wed Jun 18 12:01:02 2014");

	// Check invalid formats
	// - invalid separator characters
	CHECK(Date::fromString("WedXJun 18 12:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed JunX18 12:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18X12:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12X01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12:01X02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12:01:02X2014") == time_t(-1));
	// - weekday is not verified
	// - invalid month (must also have correct case)
	CHECK(Date::fromString("Wed Foo 18 12:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed jun 18 12:01:02 2014") == time_t(-1));
	// - invalid day
	CHECK(Date::fromString("Wed Jun 00 12:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 32 12:01:02 2014") == time_t(-1));
	// - invalid hour
	CHECK(Date::fromString("Wed Jun 18 24:01:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 xx:01:02 2014") == time_t(-1));
	// - invalid minute
	CHECK(Date::fromString("Wed Jun 18 12:60:02 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12:-1:02 2014") == time_t(-1));
	// - invalid second
	CHECK(Date::fromString("Wed Jun 18 12:01:60 2014") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12:01:0 2014 ") == time_t(-1));
	// - invalid year
	CHECK(Date::fromString("Wed Jun 18 12:01:02 1800") == time_t(-1));
	CHECK(Date::fromString("Wed Jun 18 12:01:02 X800") == time_t(-1));

	// extra characters at the end are ignored, even digits
	CHECK(Date::fromString("Wed Jun 18 12:01:02 2014x") == 1403092862);
	CHECK(Date::fromString("Wed Jun 18 12:01:02 20140") == 1403092862);
}
