#pragma once

#include "random/random.hpp"

#include <cstddef> // For size_t
#include <cstdint> // For uint64_t

namespace kuiper
{

class UUID {
  public:
    UUID()
        : m_uuid(Random::Instance().next_u64()) {}
    UUID(const std::uint64_t uuid)
        : m_uuid(uuid) {}
    UUID(const UUID&) = default;

    operator std::uint64_t() const {
        return m_uuid;
    }

  private:
    std::uint64_t m_uuid = 0;
};

} // namespace kuiper

namespace std
{
template<typename T> struct hash;

template<> struct hash<kuiper::UUID> {
    std::size_t operator()(const kuiper::UUID& uuid) const {
        // SURELY there won't be too many collisions with 2^64 possible combinations :^)
        return static_cast<uint64_t>(uuid);
    }
};
} // namespace std
