#pragma once

#include <cstdint>
#include <span>
#include <string>
#include <string_view>
#include <unordered_map>
#include <vector>

#include "application/actions/UiAction.h"
#include "application/config/ConfigOwner.h"

namespace ta::application::config
{
    class ConfigRegistry final
    {
    public:
        ConfigRegistry(ConfigOwner& global_config, std::span<ConfigOwner* const> owners);

        [[nodiscard]] ConfigValue* find_value(std::string_view key) const noexcept;
        [[nodiscard]] ta::application::UiAction* find_action(std::string_view key) const noexcept;
        [[nodiscard]] std::span<ConfigValue* const> values() const noexcept { return values_; }
        [[nodiscard]] ConfigOwner& global_config() const noexcept { return global_config_; }
        [[nodiscard]] std::span<ConfigOwner* const> owners() const noexcept { return owners_; }
        [[nodiscard]] std::uint64_t revision() const noexcept { return revision_; }

    private:
        void index_owner(ConfigOwner& owner);

        ConfigOwner& global_config_;
        std::vector<ConfigOwner*> owners_;
        std::vector<ConfigValue*> values_;
        std::unordered_map<std::string, ConfigValue*> values_by_key_;
        std::unordered_map<std::string, ta::application::UiAction*> actions_by_key_;
        std::uint64_t revision_ = 1;
    };
}
