#pragma once

#include <string>
#include <vector>
#include <memory>
#include <optional>
#include <chrono>
#include "../../../language/symbol/table.hpp"
#include "../../../language/ast/deserializer.hpp"
#include "../../../protocol/protocol.hpp"

namespace lsp::service::symbol
{
    // ==================== 文件类型 ====================

    enum class TsfFileType
    {
        kUnit,
        kClass,
        kFunction,
        kScript
    };

    // ==================== 文件符号索引 ====================

    struct Parameter
    {
        std::string name;
        std::string type;
        bool has_default = false;
    };

    struct MemberSymbol
    {
        std::string name;
        protocol::SymbolKind kind;
        std::optional<std::string> return_type;
        std::vector<Parameter> parameters;
        std::optional<language::ast::AccessModifier> access;
        bool is_class_method = false;
    };

    struct FileSymbolIndex
    {
        std::string file_path;
        TsfFileType file_type;
        protocol::DocumentUri uri;

        std::string primary_symbol;
        language::symbol::SymbolKind primary_kind;
        std::vector<MemberSymbol> exported_symbols;
    };

    // 暂时用一样的设计
    using SystemSymbolIndex = FileSymbolIndex;

    // ==================== 编辑中的符号表 ====================

    struct EditingSymbolTable
    {
        protocol::DocumentUri uri;
        protocol::integer version;
        std::string file_path;
        TsfFileType file_type;

        std::unique_ptr<language::ast::Deserializer> deserializer;
        std::unique_ptr<language::ast::Program> ast_root;
        std::unique_ptr<language::symbol::SymbolTable> symbol_table;

        std::chrono::system_clock::time_point last_parsed;
        bool is_dirty = false;
    };
}
