#pragma once

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

namespace lsp::language::symbol
{
    class ScopeManager
    {
    public:
        ScopeId CreateScope(ScopeKind kind, const ast::Location& range, std::optional<ScopeId> parent_scope_id = std::nullopt, std::optional<SymbolId> associated_symbol_id = std::nullopt);

        void AddSymbol(ScopeId scope_id, const std::string& name, SymbolId symbol_id);
        std::optional<SymbolId> FindInScope(ScopeId scope_id, const std::string& name) const;
        std::optional<SymbolId> FindInScopeChain(ScopeId scope_id, const std::string& name) const;
        const ScopeInfo* GetScopeInfo(ScopeId scope_id) const;
        std::vector<SymbolId> GetSymbolsInScope(ScopeId scope_id) const;
        ScopeId GetGlobalScope() const { return global_scope_id_; }
        const std::unordered_map<ScopeId, ScopeInfo>& GetAllScopes() const { return scopes_; }
        void Clear();

    private:
        ScopeId next_scope_id_ = 1;
        ScopeId global_scope_id_ = kInvalidScopeId;
        std::unordered_map<ScopeId, ScopeInfo> scopes_;
    };

}
