#pragma once

#include <psemek/util/uuid.hpp>
#include <psemek/util/hash.hpp>

namespace psemek::ecs::detail
{

	template <bool With>
	struct unordered_component_hasher
	{
		std::uint64_t result = 0xcd5694d2b3f3443eull;

		void operator()(util::uuid const & uuid)
		{
			if constexpr (With)
				result ^= std::hash<util::uuid>{}(uuid);
			else
				result ^= ~std::hash<util::uuid>{}(uuid);
		}
	};

	template <bool With, typename UUIDs>
	std::uint64_t unordered_component_hash(UUIDs const & uuids)
	{
		unordered_component_hasher<With> hasher;
		for (auto const & uuid : uuids)
			hasher(uuid);
		return hasher.result;
	}

	template <typename WithUUIDs, typename WithoutUUIDs>
	std::uint64_t unordered_component_hash(WithUUIDs const & with_uuids, WithoutUUIDs const & without_uuids)
	{
		return unordered_component_hash<true>(with_uuids) ^ unordered_component_hash<false>(without_uuids);
	}

}
