#include <spdlog/spdlog.h>
#include "./system.hpp"

namespace lsp::service::symbol::repository
{
    // ==================== 基础操作 ====================

    void System::Add(SystemSymbolIndex index)
    {
        std::unique_lock lock(mutex_);

        const std::string& name = index.primary_symbol;

        switch (index.file_type)
        {
        case TsfFileType::kUnit:
            units_[name] = index;
            break;
        case TsfFileType::kClass:
            classes_[name] = index;
            break;
        case TsfFileType::kFunction:
            functions_[name] = index;
            break;
        default:
            break;
        }

        spdlog::trace("Added system symbol: {}", name);
    }

    void System::Clear()
    {
        std::unique_lock lock(mutex_);
        units_.clear();
        classes_.clear();
        functions_.clear();
        spdlog::debug("Cleared system repository");
    }

    size_t System::Count() const
    {
        std::shared_lock lock(mutex_);
        return units_.size() + classes_.size() + functions_.size();
    }

    // ==================== 查找API ====================

    std::optional<SystemSymbolIndex> System::FindUnit(const std::string& name) const
    {
        std::shared_lock lock(mutex_);
        auto it = units_.find(name);
        return (it != units_.end()) ? std::optional{ it->second } : std::nullopt;
    }

    std::optional<SystemSymbolIndex> System::FindClass(const std::string& name) const
    {
        std::shared_lock lock(mutex_);
        auto it = classes_.find(name);
        return (it != classes_.end()) ? std::optional{ it->second } : std::nullopt;
    }

    std::optional<SystemSymbolIndex> System::FindFunction(const std::string& name) const
    {
        std::shared_lock lock(mutex_);
        auto it = functions_.find(name);
        return (it != functions_.end()) ? std::optional{ it->second } : std::nullopt;
    }

    // ==================== 列表API ====================

    std::vector<SystemSymbolIndex> System::Units() const
    {
        std::shared_lock lock(mutex_);
        std::vector<SystemSymbolIndex> result;
        result.reserve(units_.size());
        for (const auto& [_, index] : units_)
            result.push_back(index);
        return result;
    }

    std::vector<SystemSymbolIndex> System::Classes() const
    {
        std::shared_lock lock(mutex_);
        std::vector<SystemSymbolIndex> result;
        result.reserve(classes_.size());
        for (const auto& [_, index] : classes_)
            result.push_back(index);
        return result;
    }

    std::vector<SystemSymbolIndex> System::Functions() const
    {
        std::shared_lock lock(mutex_);
        std::vector<SystemSymbolIndex> result;
        result.reserve(functions_.size());
        for (const auto& [_, index] : functions_)
            result.push_back(index);
        return result;
    }

}
