#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>

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

extern "C" const TSLanguage* tree_sitter_tsf(void);

#include "../../src/language/ast/deserializer.hpp"
#include "./debug_printer.hpp"

using namespace lsp::language::ast;

// ==================== 文件读取 ====================

std::string ReadFile(const std::string& filepath)
{
    std::ifstream file(filepath);
    if (!file.is_open())
    {
        throw std::runtime_error("Cannot open file: " + filepath);
    }

    std::ostringstream oss;
    oss << file.rdbuf();
    return oss.str();
}

// ==================== Tree-Sitter 解析 ====================

class TreeSitterParser
{
public:
    TreeSitterParser()
    {
        parser_ = ts_parser_new();
        if (!parser_)
        {
            throw std::runtime_error("Failed to create parser");
        }

        // 设置语言
        if (!ts_parser_set_language(parser_, tree_sitter_tsf()))
        {
            ts_parser_delete(parser_);
            throw std::runtime_error("Failed to set language");
        }
    }

    ~TreeSitterParser()
    {
        if (tree_)
        {
            ts_tree_delete(tree_);
        }
        if (parser_)
        {
            ts_parser_delete(parser_);
        }
    }

    TSTree* Parse(const std::string& source)
    {
        if (tree_)
        {
            ts_tree_delete(tree_);
            tree_ = nullptr;
        }

        tree_ = ts_parser_parse_string(
            parser_,
            nullptr,
            source.c_str(),
            source.length());

        if (!tree_)
        {
            throw std::runtime_error("Failed to parse source");
        }

        return tree_;
    }

    TSNode GetRootNode()
    {
        if (!tree_)
        {
            throw std::runtime_error("No tree available");
        }
        return ts_tree_root_node(tree_);
    }

private:
    TSParser* parser_ = nullptr;
    TSTree* tree_ = nullptr;
};

// ==================== 主程序 ====================

void PrintUsage(const char* program_name)
{
    std::cout << "Usage: " << program_name << " <file_path> [options]\n";
    std::cout << "\nOptions:\n";
    std::cout << "  -v, --verbose         Show verbose output with source code\n";
    std::cout << "  -c, --compact         Use compact output mode\n";
    std::cout << "  -s, --show-source     Show source code snippets (default: off)\n";
    std::cout << "  -l, --hide-location   Hide location information\n";
    std::cout << "  -n, --no-colors       Disable colored output\n";
    std::cout << "  -t, --no-tree         Disable tree characters\n";
    std::cout << "  -k, --show-kind       Show node kind enums\n";
    std::cout << "  -i, --incremental     Test incremental parsing\n";
    std::cout << "  -h, --help            Show this help message\n";
    std::cout << "\nPreset Modes:\n";
    std::cout << "  --verbose             Equivalent to: -s -k\n";
    std::cout << "  --compact             Equivalent to: -c -l -t\n";
    std::cout << "\nExamples:\n";
    std::cout << "  " << program_name << " test.tsf\n";
    std::cout << "  " << program_name << " test.tsf --verbose\n";
    std::cout << "  " << program_name << " test.tsf --compact\n";
    std::cout << "  " << program_name << " test.tsf -s -n  # Show source without colors\n";
}

int main(int argc, char* argv[])
{
    if (argc < 2)
    {
        PrintUsage(argv[0]);
        return 1;
    }

    std::string filepath;
    bool test_incremental = false;

    // 默认打印选项
    PrintOptions opts = PrintOptions::Default();

    // 解析命令行参数
    for (int i = 1; i < argc; ++i)
    {
        std::string arg = argv[i];
        if (arg == "-h" || arg == "--help")
        {
            PrintUsage(argv[0]);
            return 0;
        }
        else if (arg == "-v" || arg == "--verbose")
        {
            opts = PrintOptions::Verbose();
        }
        else if (arg == "-c" || arg == "--compact")
        {
            opts = PrintOptions::Compact();
        }
        else if (arg == "-s" || arg == "--show-source")
        {
            opts.show_source_code = true;
        }
        else if (arg == "-l" || arg == "--hide-location")
        {
            opts.show_location = false;
        }
        else if (arg == "-n" || arg == "--no-colors")
        {
            opts.use_colors = false;
        }
        else if (arg == "-t" || arg == "--no-tree")
        {
            opts.use_tree_chars = false;
        }
        else if (arg == "-k" || arg == "--show-kind")
        {
            opts.show_node_kind = true;
        }
        else if (arg == "-i" || arg == "--incremental")
        {
            test_incremental = true;
        }
        else if (filepath.empty())
        {
            filepath = arg;
        }
        else
        {
            std::cerr << "Unknown argument: " << arg << "\n";
            return 1;
        }
    }

    try
    {
        // 读取文件
        std::cout << "Reading file: " << filepath << "\n";
        std::string source = ReadFile(filepath);
        std::cout << "File size: " << source.length() << " bytes\n\n";

        // 创建 Tree-Sitter 解析器
        TreeSitterParser ts_parser;
        [[maybe_unused]]TSTree* tree = ts_parser.Parse(source);
        TSNode root = ts_parser.GetRootNode();

        // 创建 AST 反序列化器
        Deserializer deserializer;

        ParseResult result;
        if (test_incremental)
        {
            std::cout << "Using incremental parsing...\n\n";
            auto inc_result = deserializer.ParseIncremental(root, source);
            result = std::move(inc_result.result);

            std::cout << "Incremental Parse Statistics:\n";
            std::cout << "  Nodes parsed: " << inc_result.nodes_parsed << "\n";
            std::cout << "  Nodes unchanged: " << inc_result.nodes_unchanged << "\n";
            std::cout << "  Total nodes: " << inc_result.TotalNodes() << "\n";
            std::cout << "  Change rate: " << (inc_result.ChangeRate() * 100) << "%\n\n";
        }
        else
        {
            result = deserializer.Parse(root, source);
        }

        // 打印 AST 结果（带源码）
        DebugPrint(result, source, opts);

        // 打印摘要
        std::cout << "\n";
        std::cout << Color::BrightBlue << "========================================\n"
                  << Color::Reset;
        std::cout << Color::BrightCyan << "Summary:\n"
                  << Color::Reset;
        std::cout << "  File: " << filepath << "\n";
        std::cout << "  Size: " << source.length() << " bytes\n";

        if (result.root)
        {
            std::cout << "  Statements: " << result.root->statements.size() << "\n";
        }

        std::cout << "  Errors: ";
        if (result.HasErrors())
        {
            std::cout << Color::BrightRed << result.errors.size() << " ✗" << Color::Reset << "\n";
            std::cout << "  Status: " << Color::BrightRed << "FAILED" << Color::Reset << "\n";
            return 1;
        }
        else
        {
            std::cout << Color::BrightGreen << "0 ✓" << Color::Reset << "\n";
            std::cout << "  Status: " << Color::BrightGreen << "SUCCESS" << Color::Reset << "\n";
            return 0;
        }
    }
    catch (const std::exception& e)
    {
        std::cerr << Color::BrightRed << "Error: " << e.what() << Color::Reset << "\n";
        return 1;
    }
}