#pragma once

#include <unordered_map>
#include <vector>
#include <functional>
#include "./types.hpp"

namespace lsp::language::symbol
{
    class SymbolDefinitionStore
    {
    public:
        SymbolId Add(SymbolDefinition def);

        const SymbolDefinition* Get(SymbolId id) const;

        bool Update(SymbolId id, std::function<void(SymbolDefinition&)> updater);
        bool Remove(SymbolId id);
        void Clear();

        std::vector<const SymbolDefinition*> GetAll() const;
        std::vector<const SymbolDefinition*> FindByName(const std::string& name) const;
        std::vector<SymbolId> GetChildren(SymbolId parent_id) const;

    private:
        SymbolId next_id_ = 1;
        std::unordered_map<SymbolId, SymbolDefinition> definitions_;
        std::unordered_map<std::string, std::vector<SymbolId>, utils::IHasher, utils::IEqualTo> name_index_;
        std::unordered_map<SymbolId, std::vector<SymbolId>> children_index_;

        void UpdateIndices(const SymbolDefinition& def);
        void RemoveFromIndices(const SymbolDefinition& def);
    };

}
