#ifndef _TILE_BASE_CHRONO_H
#define _TILE_BASE_CHRONO_H

#pragma once

#include "tile/base/align.h"
#include "tile/base/never_destroyed.h"

#include <atomic>
#include <chrono>
#include <memory>
#include <thread>

namespace tile {
namespace detail {
namespace chrono {

class CoarseClockInitializer {
public:
    static constexpr auto kAccuracy = std::chrono::microseconds(500);
    static CoarseClockInitializer *Instance();

    // for `tile::Start()`
    void Start();
    void Stop();
    void Join();

private:
    ~CoarseClockInitializer();
    CoarseClockInitializer();
    friend NeverDestroyedSingleton<CoarseClockInitializer>;

private:
    std::unique_ptr<std::thread> worker_;
    std::atomic<bool> running_{false};
};

}// namespace chrono
}// namespace detail

std::chrono::steady_clock::time_point ReadSteadyClock();
std::chrono::system_clock::time_point ReadSystemClock();

// accuracy: 10us
std::chrono::steady_clock::time_point ReadCoarseSteadyClock();
// accuracy: 10us
std::chrono::system_clock::time_point ReadCoarseSystemClock();

inline std::int64_t
ReadUnixTimestamp()
{
    return ReadCoarseSystemClock().time_since_epoch() / std::chrono::seconds(1);
}

}// namespace tile

#endif// _TILE_BASE_CHRONO_H
