#include "./detail.hpp"
#include "./tree_sitter_utils.hpp"
#include "./deserializer.hpp"

namespace lsp::language::ast
{
    // ==================== Deserializer 类实现 ====================

    Deserializer::Deserializer()
    {
        detail::RegisterStatementParsers();
    }

    ParseResult Deserializer::Parse(TSNode root, const std::string& source)
    {
        ParseResult result;

        detail::ParseContext ctx(source, result.errors);

        auto program = std::make_unique<Program>();
        program->span = ts::NodeLocation(root);

        uint32_t count = ts_node_child_count(root);
        for (uint32_t i = 0; i < count; i++)
        {
            TSNode child = ts_node_child(root, i);
            if (ts::IsComment(child))
                continue;
            if (!ts_node_is_named(child))
                continue;

            StatementPtr stmt = detail::ParseStatement(child, ctx);
            if (stmt)
                program->statements.push_back(std::move(stmt));
        }
        result.root = std::move(program);

        // 收集语法错误
        auto syntax_errors = detail::CollectSyntaxErrors(root, source);
        result.errors.insert(result.errors.end(),
                             std::make_move_iterator(syntax_errors.begin()),
                             std::make_move_iterator(syntax_errors.end()));

        return result;
    }

    IncrementalParseResult Deserializer::ParseIncremental(TSNode root, const std::string& source)
    {
        IncrementalParseResult result;

        detail::ParseContext ctx(source, result.result.errors);

        auto program = std::make_unique<Program>();
        program->span = ts::NodeLocation(root);

        uint32_t count = ts_node_child_count(root);
        for (uint32_t i = 0; i < count; i++)
        {
            TSNode child = ts_node_child(root, i);
            if (ts::IsComment(child))
                continue;
            if (!ts_node_is_named(child))
                continue;

            if (ts_node_has_changes(child))
                result.nodes_parsed++;
            else
                result.nodes_unchanged++;

            StatementPtr stmt = detail::ParseStatement(child, ctx);
            if (stmt)
                program->statements.push_back(std::move(stmt));
        }

        result.result.root = std::move(program);
        auto syntax_errors = detail::CollectSyntaxErrors(root, source);
        result.result.errors.insert(result.result.errors.end(),
                                    std::make_move_iterator(syntax_errors.begin()),
                                    std::make_move_iterator(syntax_errors.end()));

        return result;
    }

    std::vector<ParseError> Deserializer::DiagnoseSyntax(TSNode root, const std::string& source)
    {
        return detail::CollectSyntaxErrors(root, source);
    }

}
