/*
* 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 <vector>
#include <map>
#include <utility>
#include <type_traits>

#include "Data/Containers/BinSearchArrayMap.hpp"
#include "Data/Containers/StableVector.hpp"

using namespace OpenVulkano;

TEST_CASE("BinSearchArrayMap With Default")
{
	SECTION("Insert")
	{
		BinSearchArrayMap<int, std::string> map;

		for (int i = 0; i < 50; i++)
		{
			map.Insert(i, std::to_string(i));
		}

		REQUIRE(map.Size() == 50);
		REQUIRE(map.Get(16) == "16");
		REQUIRE(map.Get(23) == "23");
		REQUIRE(map.Get(48) == "48");
	}

	SECTION("Remove")
	{
		BinSearchArrayMap<int, std::string> map;

		for (int i = 0; i < 50; i++)
		{
			map.Insert(i, std::to_string(i));
		}

		map.Remove(16);
		map.Remove(23);
		map.Remove(48);

		REQUIRE(map.Size() == 47);

		for (int i = 0; i < 50; i++)
		{
			if (i == 16 || i == 23 || i == 48)
			{
				REQUIRE(!map.Contains(i));
			}
			else
			{
				REQUIRE(map.Get(i) == std::to_string(i));
			}
		}
	}

	SECTION("Emplace")
	{
		BinSearchArrayMap<int, std::string> map;

		for (int i = 0; i < 50; i++)
		{
			map.Emplace(i, std::to_string(i));
		}

		REQUIRE(map.Size() == 50);
		REQUIRE(map.Get(16) == "16");
		REQUIRE(map.Get(23) == "23");
		REQUIRE(map.Get(48) == "48");
	}

	SECTION("FindPair")
	{
		BinSearchArrayMap<int, std::string> map;

		for (int i = 0; i < 50; i++)
		{
			map.Insert(i, std::to_string(i));
		}

		auto pair = map.FindPair(16);
		REQUIRE(pair.first == 16);
		REQUIRE(pair.second == "16");
	}
}

TEST_CASE("BinSearchArrayMap With StableVector")
{
	SECTION("Insert")
	{
		BinSearchArrayMap<int, std::string, std::pair, StableVector> map;

		for (int i = 0; i < 50; i++)
		{
			map.Insert(i, std::to_string(i));
		}

		REQUIRE(map.Size() == 50);
		REQUIRE(map.Get(16) == "16");
		REQUIRE(map.Get(23) == "23");
		REQUIRE(map.Get(48) == "48");

		for (int i = 0; i < 50; i++)
		{
			REQUIRE(map.Get(i) == std::to_string(i));
		}
	}

	SECTION("Remove")
	{
		BinSearchArrayMap<int, std::string, std::pair, StableVector> map;

		for (int i = 0; i < 50; i++)
		{
			map.Insert(i, std::to_string(i));
		}

		map.Remove(16);
		map.Remove(23);
		map.Remove(48);

		for (int i = 0; i < 50; i++)
		{
			if (i == 16 || i == 23 || i == 48)
			{
				REQUIRE(!map.Contains(i));
			}
			else
			{
				REQUIRE(map.Get(i) == std::to_string(i));
			}
		}
	}
}