#pragma once
#include <concepts>
#include <cstddef>
#include <cstdint>
#include <optional>
#include <utility>
#include "renderive/real_time_data/Observation.hpp"
#include "renderive/real_time_data/base/Real_Time_Data_Base.hpp"
template <class That>
concept Real_Time_Data_Value = std::copy_constructible<That> && std::movable<That>;
template <class Container, class Value>
concept Real_Time_Data_History_Container = std::copy_constructible<Container> && requires(Container& container, Value value) {
    { container.push_back(std::move(value)) } -> std::same_as<void>;
    { container.clear() } -> std::same_as<void>;
    { container.size() } -> std::convertible_to<std::size_t>;
    { container.begin() };
    { container.end() };
    { container.erase(container.begin(), container.end()) };
};
template <class That>
concept Real_Time_Data = std::derived_from<That, Real_Time_Data_Base> && requires(That& data, const That& const_data, typename That::Value value) {
    typename That::Value;
    requires Real_Time_Data_Value<typename That::Value>;
    { data.update(std::move(value)) } -> std::same_as<void>;
    { const_data.revision() } -> std::same_as<std::uint64_t>;
    { const_data.update_state() } -> std::same_as<Real_Time_Data_Update_State>;
};
template <class That>
concept Latest_Real_Time_Data_Source = Real_Time_Data<That> && requires(const That& data) {
    { data.snapshot() } -> std::same_as<std::optional<typename That::Value>>;
};
template <class That>
concept History_Real_Time_Data_Source = Real_Time_Data<That> && requires(const That& data) {
    typename That::Container_Type;
    { data.snapshot() } -> std::same_as<typename That::Container_Type>;
    { data.size() } -> std::convertible_to<std::size_t>;
};
