#pragma once
#include <cstddef>
#include <cstdint>
#include <mutex>
#include <optional>
#include <utility>
#include "renderive/base/Concepts.hpp"
#include "renderive/base/observer/Observer.hpp"
#include "Observation.hpp"
#include "base/Real_Time_Data_Base.hpp"
#include "concept/Real_Time_Data.hpp"
#include "renderive/state/Render_State_View.hpp"
template <class Value_Type, Mutex_Type Mutex = std::mutex, class Observer = Observer_State<>>
class Latest_Real_Time_Data : public Real_Time_Data_Base {
public:
    using Value = Value_Type;
    static_assert(Real_Time_Data_Value<Value>);
    static_assert(Timed_Struct_Observer<Observer, Real_Time_Data_Observation>);
    explicit Latest_Real_Time_Data(Observer observer = {});
    Latest_Real_Time_Data(const Latest_Real_Time_Data&) = delete;
    Latest_Real_Time_Data& operator=(const Latest_Real_Time_Data&) = delete;
    void update(Value value);
    std::optional<Value> snapshot() const;
    bool has_value() const;
    std::uint64_t revision() const;
    Real_Time_Data_Retention retention() const noexcept override;
    Real_Time_Data_Update_State update_state() const override;
    std::size_t discard_before_time_ns(std::uint64_t time_ns) override;
    template <class Target>
    requires requires(Observer& observer, Target& target) {
        observer.bind(target);
    }
    decltype(auto) bind(Target& target) {
        return observer_.bind(target);
    }
private:
    friend class Render_State_View;
    void publish_render_state() override;
    const std::optional<Value>& render_state_value() const noexcept;
    mutable Mutex mutex_;
    std::recursive_mutex mutation_mutex_;
    Observer observer_;
    std::optional<Value> states_[3];
    std::optional<Value>* render_state_;
    std::optional<Value>* cache_state_;
    std::optional<Value>* scratch_state_;
    std::uint64_t revision_{};
    std::uint64_t render_revision_{};
    std::uint64_t total_update_count_{};
    std::uint64_t last_update_time_ns_{};
};
#include "Latest_Real_Time_Data.inl"
