#pragma once
#include "squirrel.h"
#include "sqstdaux.h"
#include "sqstdblob.h"
#include "sqstdio.h"
#include "sqstdmath.h"
#include "sqstdstring.h"
#include "sqstdsystem.h"
#include <asio.hpp>
#include <asio/ssl.hpp>
#include <asio/basic_socket_streambuf.hpp>
#include <iostream>
#include <thread>
#include <atomic>
#include <unordered_map>
#include <mutex>
#include <memory>  // 新增：用于 std::unique_ptr
#include <string>
#include <sstream>
#include <algorithm>
#include <cctype>
#include <stdint.h>

// 全局变量声明（需在cpp文件中定义）
extern HSQUIRRELVM v;
extern std::recursive_mutex SqMtx;

using tcp = asio::ip::tcp;

// ====================== 工具函数 ======================
// 字符串转小写
std::string to_lower(std::string s) {
    std::transform(s.begin(), s.end(), s.begin(),
        [](unsigned char c) { return std::tolower(c); });
    return s;
}

// 修剪字符串两端空格
std::string trim(std::string s) {
    s.erase(s.begin(), std::find_if(s.begin(), s.end(),
        [](unsigned char c) { return !std::isspace(c); }));
    s.erase(std::find_if(s.rbegin(), s.rend(),
        [](unsigned char c) { return !std::isspace(c); }).base(), s.end());
    return s;
}

// 解析 URL，分离路径和查询参数
void parse_url(const std::string& url, std::string& path, std::string& query) {
    size_t query_pos = url.find('?');
    if (query_pos == std::string::npos) {
        path = url;
        query = "";
    }
    else {
        path = url.substr(0, query_pos);
        query = url.substr(query_pos + 1);
    }
}

// ====================== HTTP 头解析结构体 ======================
struct HttpRequestHeader {
    std::string method;       // GET/POST/PUT/DELETE 等
    std::string path;         // 请求路径（如 /api/test）
    std::string version;      // HTTP/1.1 / HTTP/1.0
    std::string query_string; // URL 查询参数（如 ?id=1&name=test）
    // 头部键值对（统一转小写，避免大小写问题）
    std::unordered_map<std::string, std::string> headers;

    // 便捷获取头部值（兼容大小写）
    std::string get_header(const std::string& key) const {
        std::string lower_key = to_lower(key);
        auto it = headers.find(lower_key);
        return it != headers.end() ? it->second : "";
    }
};

// ====================== HTTP 头解析函数 ======================
HttpRequestHeader parse_http_header(const std::string& raw_header) {
    HttpRequestHeader result;
    std::istringstream iss(raw_header);
    std::string line;
    bool first_line_parsed = false;

    // 第一步：解析请求首行（仅解析第一行，避免重复）
    while (std::getline(iss, line)) {
        // 移除行尾的 \r
        if (!line.empty() && line.back() == '\r') {
            line.pop_back();
        }
        line = trim(line);

        // 跳过空行
        if (line.empty()) {
            continue;
        }

        // 仅解析第一个非空行作为请求首行
        if (!first_line_parsed) {
            std::string url;
            std::istringstream line_iss(line);
            line_iss >> result.method >> url >> result.version;
            parse_url(url, result.path, result.query_string);
            std::transform(result.method.begin(), result.method.end(), result.method.begin(),
                [](unsigned char c) { return std::toupper(c); });
            first_line_parsed = true;
            continue;
        }

        // 解析头部键值对
        size_t colon_pos = line.find(':');
        if (colon_pos == std::string::npos) {
            continue;
        }

        std::string key = trim(line.substr(0, colon_pos));
        std::string value = trim(line.substr(colon_pos + 1));
        result.headers[to_lower(key)] = value;
    }

    return result;
}

// ====================== 读取完整原始请求 ======================
std::string read_full_raw_request(tcp::socket& socket, HttpRequestHeader& header_out) {
    asio::streambuf buf;
    std::string full_request;
    asio::error_code ec;

    try {
        // 第一步：读取头部（直到 \r\n\r\n）
        size_t header_bytes = asio::read_until(socket, buf, "\r\n\r\n", ec);
        if (ec) {
            throw asio::system_error(ec);
        }

        // 提取头部内容
        std::string header_str(asio::buffer_cast<const char*>(buf.data()), header_bytes);
        full_request = header_str;

        // 安全清理头部末尾的 \r\n\r\n（核心修复：先判断是否找到）
        size_t end_header_pos = header_str.find("\r\n\r\n"); // 用 find 而非 find_last_of，精准匹配结束符
        if (end_header_pos != std::string::npos) {
            // 只保留头部内容，截断后面的空行
            header_str = header_str.substr(0, end_header_pos);
        }

        // 解析头部
        header_out = parse_http_header(header_str);

        // 第二步：读取请求体（严格按 Content-Length 读取）
        size_t content_len = 0;
        std::string cl_str = header_out.get_header("Content-Length");
        if (!cl_str.empty()) {
            try {
                content_len = std::stoul(cl_str);
            }
            catch (...) {
                content_len = 0;
            }
        }

        // 清空缓冲区中已读取的头部数据
        buf.consume(header_bytes);

        // 读取请求体（防越界）
        if (content_len > 0) {
            // 先检查剩余缓冲区是否足够，避免读取超限
            size_t buf_available = buf.size();
            if (buf_available < content_len) {
                // 读取剩余需要的字节
                asio::read(socket, buf, asio::transfer_exactly(content_len - buf_available), ec);
                if (ec && ec != asio::error::eof) {
                    throw asio::system_error(ec);
                }
            }

            // 提取请求体（防缓冲区数据不足）
            size_t actual_read = std::min(buf.size(), content_len);
            std::string body_str(asio::buffer_cast<const char*>(buf.data()), actual_read);
            full_request += body_str;

            // 清理缓冲区
            buf.consume(actual_read);
        }
    }
    catch (...) {
        throw;
    }

    return full_request;
}

// ====================== 将 HttpRequestHeader 转为 Squirrel Table ======================
void push_http_header_to_squirrel(HSQUIRRELVM v, const HttpRequestHeader& header) {
    // 1. 创建空 Table
    sq_newtable(v);

    // 2. 设置基础字段（method/path/version/query_string）
    // method
    sq_pushstring(v, _SC("method"), -1);
    sq_pushstring(v, header.method.c_str(), -1);
    sq_rawset(v, -3);

    // path
    sq_pushstring(v, _SC("path"), -1);
    sq_pushstring(v, header.path.c_str(), -1);
    sq_rawset(v, -3);

    // version
    sq_pushstring(v, _SC("version"), -1);
    sq_pushstring(v, header.version.c_str(), -1);
    sq_rawset(v, -3);

    // query_string
    sq_pushstring(v, _SC("query_string"), -1);
    sq_pushstring(v, header.query_string.c_str(), -1);
    sq_rawset(v, -3);

    // 3. 创建 headers 子 Table
    sq_pushstring(v, _SC("headers"), -1);
    sq_newtable(v);
    // 遍历头部键值对，写入子 Table
    for (const auto& pair : header.headers) {
        sq_pushstring(v, pair.first.c_str(), -1); // 键（小写）
        sq_pushstring(v, pair.second.c_str(), -1); // 值
        sq_rawset(v, -3);
    }
    // 将 headers 子 Table 写入主 Table
    sq_rawset(v, -3);
}

// ====================== 处理客户端请求 ======================
void handle_client(tcp::socket* socket, HSQOBJECT HttpServerObject) {
    if (!socket || !socket->is_open()) {
        std::cerr << "无效的 socket 连接" << std::endl;
        return;
    }

    try {
        // 读取完整请求并解析头部
        HttpRequestHeader header;
        std::string full_request = read_full_raw_request(*socket, header);

        // 加锁操作 Squirrel VM（lock_guard 自动管理锁生命周期）
        std::lock_guard<std::recursive_mutex> lock(SqMtx);

        // 执行 Squirrel 的 Event 函数
        SQInteger top = sq_gettop(v); // 保存栈状态
        sq_pushobject(v, HttpServerObject);
        sq_pushstring(v, _SC("Event"), -1);

        if (SQ_SUCCEEDED(sq_get(v, -2))) {
            // 压入函数参数：
            // 参数1：HttpServerObject（this）
            sq_pushobject(v, HttpServerObject);
            // 参数2：socket 指针（userpointer）
            sq_pushuserpointer(v, socket);
            // 参数3：解析后的 header table
            push_http_header_to_squirrel(v, header);
            // 参数4：完整原始请求字符串
            size_t body_start_pos = full_request.find("\r\n\r\n");
            std::string request_body = (body_start_pos != std::string::npos) ? full_request.substr(body_start_pos + 4) : "";
            sq_pushstring(v, request_body.c_str(), request_body.size());

            // 调用函数：参数数量=4，无返回值，开启错误捕获
            sq_call(v, 4, SQFalse, SQTrue);
        }

        sq_settop(v, top); // 恢复栈状态

    }
    catch (const asio::system_error& e) {
        std::cerr << "网络错误: " << e.what() << " (错误码: " << e.code() << ")" << std::endl;
    }
    catch (const std::exception& e) {
        std::cerr << "处理请求错误: " << e.what() << std::endl;
    }
    catch (...) {
        std::cerr << "未知错误" << std::endl;
    }
}

// ====================== 服务器上下文（支持多实例） ======================
struct HttpServerCtx {
    uint64_t server_id;                  // 唯一服务器ID（多实例核心）
    std::atomic<bool> running{ true };     // 退出标志（atomic不可拷贝）
    HSQUIRRELVM vm;                      // Squirrel VM
    HSQOBJECT http_server_obj;           // 保存的对象
    asio::io_context* io_context = nullptr; // IO上下文（用于停止）
    std::string host;                    // 记录主机（调试用）
    std::string port;                    // 记录端口（调试用）

    // 禁用拷贝构造和赋值（显式声明，避免误拷贝）
    HttpServerCtx(const HttpServerCtx&) = delete;
    HttpServerCtx& operator=(const HttpServerCtx&) = delete;

    // 允许移动构造（用于unique_ptr）
    HttpServerCtx(HttpServerCtx&&) = default;
    HttpServerCtx& operator=(HttpServerCtx&&) = default;

    // 构造函数
    HttpServerCtx() = default;
    HttpServerCtx(uint64_t id, HSQUIRRELVM vm_ptr, HSQOBJECT obj, const std::string& h, const std::string& p)
        : server_id(id), vm(vm_ptr), http_server_obj(obj), host(h), port(p) {
    }
};

// ====================== 全局服务器管理（核心修复：用unique_ptr存储，避免拷贝） ======================
static std::unordered_map<uint64_t, std::unique_ptr<HttpServerCtx>> g_server_ctxs;
static std::atomic<uint64_t> g_next_server_id{ 1 }; // 自增唯一ID（atomic不可拷贝，直接用）
static std::mutex g_server_mutex;                  // 保护全局容器

// ====================== 服务器主函数 ======================
void start_server(uint64_t server_id, const std::string& host, const std::string& port) {
    // 查找上下文（加锁）
    std::unique_lock<std::mutex> lock(g_server_mutex);
    auto it = g_server_ctxs.find(server_id);
    if (it == g_server_ctxs.end()) {
        std::cerr << "服务器上下文不存在 (ID: " << server_id << ")" << std::endl;
        return;
    }
    HttpServerCtx* ctx = it->second.get(); // 获取指针，不拷贝
    lock.unlock(); // 手动解锁

    asio::io_context io_context;
    ctx->io_context = &io_context; // 关联IO上下文

    try {
        tcp::acceptor acceptor(io_context, tcp::endpoint(asio::ip::make_address(host), std::stoi(port)));
        std::cout << "Server [" << server_id << "] listening on " << host << ":" << port << std::endl;

        // 循环监听（支持退出）
        while (ctx->running.load(std::memory_order_relaxed)) { // 原子操作读取
            tcp::socket* socket = new tcp::socket(io_context);
            try {
                acceptor.accept(*socket);
                // 启动客户端处理线程
                std::thread(handle_client, std::move(socket), ctx->http_server_obj).detach();
            }
            catch (const asio::system_error& e) {
                delete socket; // 中断时释放Socket
                if (e.code() != asio::error::operation_aborted && ctx->running.load(std::memory_order_relaxed)) {
                    std::cerr << "Server [" << server_id << "] Accept error: " << e.what() << std::endl;
                }
            }
        }
    }
    catch (const std::exception& e) {
        std::cerr << "Server [" << server_id << "] error: " << e.what() << std::endl;
    }

    // 停止IO上下文
    io_context.stop();
    std::cout << "Server [" << server_id << "] stopped" << std::endl;
}

// ====================== Squirrel 绑定函数 - 创建HTTP客户端 ======================
static SQInteger CreateHttp(HSQUIRRELVM v) {
    const SQChar* Host;
    sq_getstring(v, 2, &Host);
    const SQChar* Service;
    sq_getstring(v, 3, &Service);
    const SQChar* Content;
    sq_getstring(v, 4, &Content);

    try {
        asio::io_context ioContext;
        asio::ip::tcp::resolver resolver(ioContext);
        auto endpoints = resolver.resolve(Host, Service);
        asio::ip::tcp::socket socket(ioContext);
        asio::connect(socket, endpoints);

        // 发送HTTP请求
        std::string request = Content;
        asio::write(socket, asio::buffer(request));

        // 读取响应
        asio::streambuf response;
        asio::error_code error;
        while (asio::read(socket, response, asio::transfer_at_least(1), error)) {}

        if (error && error != asio::error::eof) {
            throw asio::system_error(error);
        }

        // 将响应内容返回
        std::istream responseStream(&response);
        std::ostringstream oss;
        oss << responseStream.rdbuf();
        sq_pushstring(v, oss.str().c_str(), -1);
        return 1;
    }
    catch (const std::exception& e) {
        return sq_throwerror(v, e.what());
    }
    catch (...) {
        return sq_throwerror(v, _SC("Unknown error occurred"));
    }
}

// ====================== Squirrel 绑定函数 - 创建HTTP服务器（核心修复：避免拷贝atomic） ======================
static SQInteger CreateHttpServer(HSQUIRRELVM v) {
    const SQChar* host = nullptr;
    const SQChar* port = nullptr;
    HSQOBJECT HttpServerObject;

    // 1. 参数校验
    if (SQ_FAILED(sq_getstring(v, 2, &host)) ||
        SQ_FAILED(sq_getstring(v, 3, &port)) ||
        SQ_FAILED(sq_getstackobj(v, 4, &HttpServerObject))) {
        sq_pushstring(v, _SC("param error: need (host:str, port:str, obj:HSQOBJECT)"), -1);
        return SQ_ERROR;
    }

    // 2. 生成唯一服务器ID
    uint64_t server_id = g_next_server_id.fetch_add(1, std::memory_order_relaxed);

    try {
        // 3. 动态创建上下文（避免拷贝）
        auto ctx_ptr = std::unique_ptr<HttpServerCtx>(new HttpServerCtx(server_id, v, HttpServerObject, std::string(host), std::string(port)));
        sq_addref(v, &ctx_ptr->http_server_obj); // 增加引用

        // 4. 加锁存入全局（移动语义，不拷贝）
        std::lock_guard<std::mutex> lock(g_server_mutex);
        g_server_ctxs[server_id] = std::move(ctx_ptr); // 移动unique_ptr，不拷贝atomic

        // 5. 启动服务器线程
        std::thread server_thread(start_server, server_id, std::string(host), std::string(port));
        server_thread.detach();

        // 6. 返回唯一ID给Squirrel
        sq_pushinteger(v, static_cast<SQInteger>(server_id));
        return 1;
    }
    catch (...) {
        // 异常清理
        sq_release(v, &HttpServerObject); // 直接释放传入的对象
        std::lock_guard<std::mutex> lock(g_server_mutex);
        g_server_ctxs.erase(server_id);
        sq_pushbool(v, false);
        return 1;
    }
}

// ====================== Squirrel 绑定函数 - 停止HTTP服务器 ======================
static SQInteger StopHttpServer(HSQUIRRELVM v) {
    SQInteger server_id_int;
    if (SQ_FAILED(sq_getinteger(v, 2, &server_id_int)) || server_id_int <= 0) {
        sq_pushstring(v, _SC("invalid server ID"), -1);
        return SQ_ERROR;
    }
    uint64_t server_id = static_cast<uint64_t>(server_id_int);

    std::lock_guard<std::mutex> lock(g_server_mutex);
    auto it = g_server_ctxs.find(server_id);
    if (it == g_server_ctxs.end()) {
        // 修正：拼接错误信息中的 server ID
        std::string err_msg = "server instance not found (ID: " + std::to_string(server_id) + ")";
        sq_pushstring(v, err_msg.c_str(), -1);
        return SQ_ERROR;
    }
    HttpServerCtx* ctx = it->second.get();

    // 1. 标记停止（原子操作）
    ctx->running.store(false, std::memory_order_relaxed);
    
    // 2. 强制停止 IO 上下文（中断所有异步操作）
    if (ctx->io_context) {
        ctx->io_context->stop();
    }

    // 3. 释放 Squirrel 引用
    sq_release(ctx->vm, &ctx->http_server_obj);

    // 4. 移除上下文（unique_ptr 自动析构）
    g_server_ctxs.erase(it);

    sq_pushbool(v, true);
    return 1;
}

// ====================== Squirrel 绑定函数 - 发送HTTP响应 ======================
static SQInteger HttpServerResponse_Write(HSQUIRRELVM v) {
    SQUserPointer P;
    if (SQ_FAILED(sq_getuserpointer(v, 2, &P))) {
        return sq_throwerror(v, _SC("invalid socket pointer"));
    }
    tcp::socket* socket = static_cast<tcp::socket*>(P);

    const SQChar* Content;
    if (SQ_FAILED(sq_getstring(v, 3, &Content))) {
        return sq_throwerror(v, _SC("invalid response content"));
    }

    try {
        if (socket && socket->is_open()) {
            std::string response = Content;
            asio::write(*socket, asio::buffer(response));
        }
    }
    catch (const std::exception& e) {
        // 清理资源
        if (socket) {
            asio::error_code ec;
            socket->close(ec);
            delete socket;
        }
        return sq_throwerror(v, e.what());
    }
    catch (...) {
        if (socket) {
            asio::error_code ec;
            socket->close(ec);
            delete socket;
        }
        return sq_throwerror(v, _SC("Unknown error occurred"));
    }

    // 最后清理socket
    if (socket) {
        asio::error_code ec;
        socket->close(ec);
        delete socket;
    }
    return 0;
}

// ====================== 辅助函数 - 注册Squirrel函数 ======================
static SQInteger register_Dio_func(HSQUIRRELVM v, SQFUNCTION f, const char* fname) {
    sq_pushroottable(v);
    sq_pushstring(v, fname, -1);
    sq_newclosure(v, f, 0);
    sq_newslot(v, -3, SQFalse);
    sq_pop(v, 1); // 弹出根表
    return 0;
}

// ====================== 注册所有Dio函数 ======================
static void RegisterDio(HSQUIRRELVM v) {
    // 创建HTTP客户端
    register_Dio_func(v, CreateHttp, _SC("Sq_CreateHttp"));
    // HTTP服务器相关
    register_Dio_func(v, CreateHttpServer, _SC("Sq_CreateHttpServer"));
    register_Dio_func(v, StopHttpServer, _SC("Sq_StopHttpServer"));
    // 发送HTTP响应
    register_Dio_func(v, HttpServerResponse_Write, _SC("Sq_HttpServerResponse_Write"));
}