/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

#include <catch2/catch_all.hpp>

#include "Math/Timestamp.hpp"

using namespace OpenVulkano::Math;

TEST_CASE("Constructors", "[Timestamp]")
{
	Timestamp ts;
	REQUIRE(ts.GetNanos() == 0);
	REQUIRE(ts.GetSeconds() == 0.0);

	ts = Timestamp((uint64_t)1'000'000'000ull); // 1 second
	REQUIRE(ts.GetNanos() == 1'000'000'000ull);
	REQUIRE(ts.GetSeconds() == 1.0);

	ts = Timestamp(2.5); // 2.5 seconds
	REQUIRE(ts.GetNanos() == 2'500'000'000ull);
	REQUIRE(ts.GetSeconds() == 2.5);
}

TEST_CASE("Arithmetic operations", "[Timestamp]")
{
	Timestamp ts1((uint64_t)1'000'000'000ull); // 1 second
	Timestamp ts2((uint64_t)2'000'000'000ull); // 2 seconds
	Timestamp result;

	result = ts1 + ts2;
	REQUIRE(result.GetNanos() == 3'000'000'000ull);

	result = ts2 - ts1;
	REQUIRE(result.GetNanos() == 1'000'000'000ull);

	ts1 += ts2;
	REQUIRE(ts1.GetNanos() == 3'000'000'000ull);

	ts1 -= ts2;
	ts1 -= ts2; // Wraps around
	REQUIRE(ts1.GetNanos() > 0);
}

TEST_CASE("Comparison operators", "[Timestamp]")
{
	Timestamp ts1((uint64_t)1'000'000'000ull); // 1 second
	Timestamp ts2((uint64_t)2'000'000'000ull); // 2 seconds
	Timestamp ts3((uint64_t)1'000'000'000ull);

	REQUIRE(ts1 == ts3);
	REQUIRE(ts1 != ts2);
	REQUIRE(ts1 < ts2);
	REQUIRE(ts2 > ts1);
	REQUIRE(ts1 <= ts3);
	REQUIRE(ts2 >= ts1);
}

TEST_CASE("Assignment operators", "[Timestamp]")
{
	Timestamp ts;
	ts = (uint64_t)1'000'000'000ull;
	REQUIRE(ts.GetNanos() == 1'000'000'000ull);

	ts = 2.0;
	REQUIRE(ts.GetNanos() == 2'000'000'000ull);
}

TEST_CASE("Division operator", "[Timestamp]")
{
	Timestamp ts1(2.0);
	Timestamp ts2(1.0);

	double result = ts1 / ts2;
	REQUIRE(result == 2.0);
}
