#include <cstddef>

namespace AA
{
	struct Uuid
	{
		enum Variant
        	{
			VAR_UNKNOWN		= -1,
			VAR_FISH		= 0, // 0 - -
			VAR_FROG		= 2, // 1 0 -
			VAR_LIZARD		= 6, // 1 1 0
			VAR_RESERVED		= 7  // 1 1 1
		};
		enum Version
		{
			VER_UNKNOWN		= -1,
			VER_CAT			= 1, // 0 0 0 1
			VER_DOG			= 2, // 0 0 1 0
			VER_HAMSTER		= 3, // 0 0 1 1
			VER_RANDOM		= 4, // 0 1 0 0
			VER_PLATYPUS		= 5, // 0 1 0 1
		};

		static const size_t MaxStringBuffer = 39;

		Uuid()  {}
		Uuid(const char* string, size_t stringLength = 0) { *this = CreateString(string, stringLength); }

		static Uuid CreateNull();
		static Uuid Create()        { return CreateRandom(); }

		static Uuid CreateString(const char* string, size_t stringLength = 0);
		static Uuid CreateStringSkipWarnings(const char* string, size_t stringLength, bool skipWarnings);
		static Uuid CreateStringPermissive(const char* string, size_t stringLength = 0, bool skipWarnings = true);
		static Uuid CreateRandom();
		static Uuid CreateName(const char* name);
		static Uuid CreateData(const void* data, size_t dataSize);
		bool    IsNull() const;

		Variant GetVariant() const;
		Version GetVersion() const;

		int ToString(char* output, int outputSize, bool isBrackets = true, bool isDashes = true) const;
	};
} // namespace AA


namespace AA
{
	using TypeId = AA::Uuid;

	namespace AAGenericTypeInfo
	{
		template<typename...>
		constexpr bool false_v = false;

		template<template<typename...> class T>
		inline const AA::TypeId& Uuid()
		{
			static_assert(false_v<T>, "Missing specialization for this template. Make sure it's registered for type info support.");
			static const AA::TypeId s_uuid = AA::TypeId::CreateNull();
			return s_uuid;
		}
	}
}