#include "connector_controller.h"

#define BUFFER_SIZE 1024
#define HTTP_SERVER_PORT 8080

std::vector<std::thread> threads; // 存储所有连接线程
std::map<int, int> sockets; // 存储套接字
std::mutex sockets_mutex; // 用于同步访问 sockets
std::atomic<bool> exit_flag(false); // 原子退出标志


// 维护连接的函数
void KeepConnection(int sock) {
    char buffer[BUFFER_SIZE];
    int nbytes;
    while (!exit_flag) {
        nbytes = recv(sock, buffer, BUFFER_SIZE, 0);
        if (nbytes <= 0) {
            std::cout << "Gateway disconnected" << std::endl;
            break;
        }
        std::cout << "Received from gateway (Socket " << sock << "): " << buffer << std::endl;
    }

    {
        std::lock_guard<std::mutex> lock(sockets_mutex);
        sockets.erase(sock); // 从集合中移除套接字
    }
    close(sock);
}
// 连接到网关的函数
void ConnectToGateway(const std::string& ip, int port) {
    int sock = socket(AF_INET, SOCK_STREAM, 0);
    if (sock < 0) {
        perror("Could not create socket");
        return;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(port);
    if (inet_pton(AF_INET, ip.c_str(), &server_addr.sin_addr) <= 0) {
        perror("Invalid address");
        close(sock);
        return;
    }

    if (connect(sock, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Connection to the server failed");
        close(sock);
        return;
    }

    {
        std::lock_guard<std::mutex> lock(sockets_mutex);
        sockets[sock] = 1; // 将套接字添加到集合中
    }

    std::cout << "Connected to gateway at " << ip << ":" << port << " (Socket " << sock << ")" << std::endl;

    // 在新线程中维护连接
    threads.emplace_back(KeepConnection, sock);
}

// 处理HTTP请求的函数
void HandleHttpRequest(int client_socket) {
    char buffer[BUFFER_SIZE];
    int bytes_read = recv(client_socket, buffer, sizeof(buffer), 0);
    if (bytes_read <= 0) {
        close(client_socket);
        return;
    }

    // 简单解析HTTP请求
    std::string http_request(buffer, bytes_read);
    std::string ip;
    int port;
    
    // 寻找IP和端口号
    auto host_pos = http_request.find("Host: ");
    if (host_pos != std::string::npos) {
        auto start = host_pos + std::string("Host: ").size();
        ip = http_request.substr(start, http_request.find("\r\n", start) - start);
    }

    auto content_length_pos = http_request.find("Content-Length:");
    if (content_length_pos != std::string::npos) {
        auto start = content_length_pos + std::string("Content-Length: ").size();
        int length = std::stoi(http_request.substr(start, http_request.find("\r\n", start) - start));
        if (length > 0) {
            char* content = new char[length];
            bytes_read = recv(client_socket, content, length, 0);
            if (bytes_read > 0) {
                // 解析JSON内容（假设前端发送的是JSON格式）
                // 这里需要添加JSON解析逻辑来提取IP和端口
                // 示例：{"ip":"192.168.1.1","port":8080}
                // 可以使用第三方库如nlohmann/json来解析JSON

                // 假设解析后得到ip和port
                // ConnectToGateway(ip, port);

                delete[] content;
            }
        }
    }

    // 发送HTTP响应
    std::string response = "HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\n\r\n";
    send(client_socket, response.c_str(), response.size(), 0);
    close(client_socket);
}

// 启动HTTP服务器的函数
void StartHttpServer() {
    int http_server_socket = socket(AF_INET, SOCK_STREAM, 0);
    if (http_server_socket < 0) {
        perror("Could not create HTTP server socket");
        return;
    }

    int opt = 1;
    if (setsockopt(http_server_socket, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) {
        perror("Setsockopt failed");
        close(http_server_socket);
        return;
    }

    struct sockaddr_in server_addr;
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY;
    server_addr.sin_port = htons(HTTP_SERVER_PORT);

    if (bind(http_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) {
        perror("Bind failed");
        close(http_server_socket);
        return;
    }

    if (listen(http_server_socket, 5) < 0) {
        perror("Listen failed");
        close(http_server_socket);
        return;
    }

    std::cout << "HTTP server listening on port " << HTTP_SERVER_PORT << std::endl;

    while (!exit_flag) {
        int client_socket = accept(http_server_socket, NULL, NULL);
        if (client_socket < 0) {
            perror("Accept failed");
            continue;
        }

        threads.emplace_back(HandleHttpRequest, client_socket);
    }

    close(http_server_socket);
}

/*
int main() {
    // threads.emplace_back(StartHttpServer);

    // std::string command, ip;
    // int port;
    // bool in_connect_mode = false;
    // std::cout << "Enter command (connect/exit): ";
    // while (true) {
        
    //     if (in_connect_mode)
    //     {   
    //         std::cout << "continue connect or not ? (y or n) ";
    //         std::cin >> command;
    //         if(command=="y"){
    //             std::cout << "Enter the gateway IP address: ";
    //             std::cin >> ip;
    //             std::cout << "Enter the gateway port: ";
    //             std::cin >> port;
    //             ConnectToGateway(ip, port);
    //         }
    //         else {
    //             in_connect_mode = false; // 退出连接模式
    //             std::cout << "Exiting connect mode." << std::endl;
    //         }          
    //     }
    //     else{
    //         std::cout << "Enter command (connect/exit): ";
    //         std::cin>>command;
    //     if (command == "connect") {
    //         if (in_connect_mode) {
    //             std::cout << "Already in connect mode." << std::endl;
    //             continue;
    //         }
    //         in_connect_mode = true; // 进入连接模式
    //         std::cout << "Enter the gateway IP address: ";
    //         std::cin >> ip;
    //         std::cout << "Enter the gateway port: ";
    //         std::cin >> port;
    //         ConnectToGateway(ip, port);
    //     } else if (command == "exit") {
    //         exit_flag = true; // 设置退出标志
    //         std::cout << "Exiting program." << std::endl;
    //         // 关闭所有套接字
    //         for (auto& sock_pair : sockets) {
    //             shutdown(sock_pair.first, SHUT_RDWR); // 关闭套接字的发送和接收
    //             close(sock_pair.first);
    //         }
    //         sockets.clear();
    //         std::cout << "sockets.clear" << std::endl;
    //         // 等待所有线程结束
    //         for (auto& thread : threads) {
    //             if (thread.joinable()) {
    //                 thread.join();
    //             }
    //         }
    //         threads.clear();
    //         break; // 退出主循环
    //     } else {
    //         std::cout << "Unknown command" << std::endl;
    //     }
    //     }
    // }
    // std::cout<<"out"<<std::endl;
    // return 0;
    std::thread http_server_thread(StartHttpServer);

    std::string command, ip;
    int port;
    bool in_connect_mode = false;

    while (true) {
        std::cout << "Enter command (connect/exit): ";
        std::cin >> command;

        if (command == "connect") {
            if (in_connect_mode) {
                std::cout << "Already in connect mode." << std::endl;
                continue;
            }
            in_connect_mode = true;
            std::cout << "Enter the gateway IP address: ";
            std::cin >> ip;
            std::cout << "Enter the gateway port: ";
            std::cin >> port;
            ConnectToGateway(ip, port);
        } else if (command == "exit") {
            break; // 接收到退出命令，退出主循环
        } else {
            std::cout << "Unknown command" << std::endl;
        }
    }

    // 设置退出标志
    exit_flag = true;

    // 强制结束HTTP服务器线程
    if (http_server_thread.joinable()) {
        http_server_thread.join();
    }

    // 关闭所有套接字
    for (auto& sock_pair : sockets) {
        shutdown(sock_pair.first, SHUT_RDWR);
        close(sock_pair.first);
    }
    sockets.clear();

    // 等待所有工作线程结束
    for (auto& thread : threads) {
        if (thread.joinable()) {
            thread.join();
        }
    }
    threads.clear();

    std::cout << "Exited program." << std::endl;
    return 0;

}
*/