#pragma once

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

extern "C" {
#include <tree_sitter/api.h>
}

namespace lsp::language::ast
{
    // ===== 解析错误 =====
    enum class ErrorSeverity
    {
        Warning,
        Error,
        Fatal
    };

    struct ParseError
    {
        Location location;
        std::string node_type;
        std::string message;
        ErrorSeverity severity = ErrorSeverity::Error;

        static ParseError Create(const Location& loc, const std::string& type, const std::string& msg)
        {
            return { loc, type, msg, ErrorSeverity::Error };
        }

        static ParseError Missing(const Location& loc, const std::string& type)
        {
            return Create(loc, type, "Syntax error: missing " + type);
        }

        static ParseError Unexpected(const Location& loc, const std::string& type, const std::string& context = "")
        {
            std::string msg = "Syntax error: unexpected token";
            if (!context.empty())
                msg += " in " + context;
            return Create(loc, type, msg);
        }
    };

    // ===== 解析结果 =====
    struct ParseResult
    {
        std::unique_ptr<Program> root;
        std::vector<ParseError> errors;

        bool HasErrors() const { return !errors.empty(); }
        bool IsSuccess() const { return errors.empty(); }
        size_t ErrorCount() const { return errors.size(); }
    };

    // ===== 增量解析结果 =====
    struct IncrementalParseResult
    {
        ParseResult result;
        size_t nodes_parsed = 0; // 重新解析的节点数
        size_t nodes_unchanged = 0; // 未变化的节点数

        size_t TotalNodes() const { return nodes_parsed + nodes_unchanged; }
        double ChangeRate() const
        {
            return TotalNodes() > 0 ? static_cast<double>(nodes_parsed) / TotalNodes() : 0.0;
        }
    };

    // ===== Deserializer 类 =====
    class Deserializer
    {
    public:
        Deserializer();
        ~Deserializer() = default;
        Deserializer(const Deserializer&) = delete;
        Deserializer& operator=(const Deserializer&) = delete;

        ParseResult Parse(TSNode root, const std::string& source);
        IncrementalParseResult ParseIncremental(TSNode root, const std::string& source);

        static std::vector<ParseError> DiagnoseSyntax(TSNode root, const std::string& source);
    };

}
