/*********************************************************************
 * \file   Time.hpp
 *
 * \author Romain BOULLARD
 * \date   December 2025
 *********************************************************************/
#ifndef BIGFOOT_SYSTEM_TIME_TIME_HPP
#define BIGFOOT_SYSTEM_TIME_TIME_HPP
#include <chrono>
#include <compare>
#include <cstdint>

namespace Bigfoot
{
class Time
{
  public:
    Time(const std::uint64_t p_epoch);

    Time(const Time& p_time) = default;
    Time(Time&& p_time) = default;

    [[nodiscard]]
    std::uint32_t GetYear() const;

    [[nodiscard]]
    std::uint32_t GetMonth() const;

    [[nodiscard]]
    std::uint32_t GetDay() const;

    [[nodiscard]]
    std::uint32_t GetHour() const;

    [[nodiscard]]
    std::uint32_t GetMinute() const;

    [[nodiscard]]
    std::uint32_t GetSecond() const;

    [[nodiscard]]
    std::uint32_t GetMicrosecond() const;

    [[nodiscard]]
    std::uint64_t GetEpoch() const;

    ~Time() = default;

    Time& operator=(const Time& p_time) = default;
    Time& operator=(Time&& p_time) = default;

    [[nodiscard]]
    auto operator<=>(const Time& p_other) const
    {
        return m_epoch <=> p_other.m_epoch;
    }

    [[nodiscard]]
    static Time Now();

  private:
    std::uint64_t m_epoch;
    std::tm m_timeInfo;
    std::chrono::microseconds m_microseconds;
};
}   // namespace Bigfoot

/****************************************************************************************/

namespace Flat
{
namespace Bigfoot
{
struct Time;
}
}   // namespace Flat

/****************************************************************************************/

namespace flatbuffers
{
Flat::Bigfoot::Time Pack(const Bigfoot::Time& p_time);
Bigfoot::Time UnPack(const Flat::Bigfoot::Time& p_flatTime);
}   // namespace flatbuffers

#endif
