#include <iostream>
#include <string>
#include <vector>
#include <chrono>
#include <thread>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <random>
#include <deque>
#include <mutex>
#include <atomic>

#ifdef _WIN32
#include <windows.h>
#else
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#endif

class USBController {
private:
    std::string port_name;
    int baud_rate;
    
#ifdef _WIN32
    HANDLE hSerial;
#else
    int serial_fd;
#endif
    
    std::string log_file;
    std::deque<std::string> command_history;
    std::mutex log_mutex;
    
    struct ControllerState {
        std::string mode;
        std::vector<int> active_channels;
        bool pc_enabled;
    } current_state;
    
    std::atomic<bool> is_connected{false};
    
    void log_to_file(const std::string& message) {
        std::lock_guard<std::mutex> lock(log_mutex);
        std::ofstream log_stream(log_file, std::ios::app);
        if (log_stream.is_open()) {
            auto now = std::chrono::system_clock::now();
            auto now_time = std::chrono::system_clock::to_time_t(now);
            log_stream << "[" << std::put_time(std::localtime(&now_time), "%Y-%m-%d %H:%M:%S")
                      << "] " << message << std::endl;
        }
    }
    
    void update_state_from_response(const std::string& response, const std::string& command) {
        std::string response_lower;
        std::transform(response.begin(), response.end(), std::back_inserter(response_lower), ::tolower);
        
        if (response_lower.find("standby") != std::string::npos) {
            current_state.mode = "standby";
            current_state.active_channels.clear();
            current_state.pc_enabled = false;
        } else if (response_lower.find("power mode") != std::string::npos) {
            current_state.mode = "power";
            // 提取通道号
            for (int i = 1; i <= 8; i++) {
                std::string channel_str = "channel " + std::to_string(i);
                if (response_lower.find(channel_str) != std::string::npos) {
                    bool found = false;
                    for (int ch : current_state.active_channels) {
                        if (ch == i) {
                            found = true;
                            break;
                        }
                    }
                    if (!found) {
                        current_state.active_channels.push_back(i);
                    }
                    current_state.pc_enabled = false;
                    break;
                }
            }
        } else if (response_lower.find("pc data mode") != std::string::npos || 
                   response_lower.find("pc mode") != std::string::npos) {
            current_state.mode = "pc";
            current_state.pc_enabled = true;
            current_state.active_channels.clear();
        }
    }
    
public:
    USBController(const std::string& port, int baud) 
        : port_name(port), baud_rate(baud), log_file("usb_controller_cpp.log") {
        current_state.mode = "standby";
        current_state.pc_enabled = false;
    }
    
    ~USBController() {
        disconnect();
    }
    
    bool connect() {
#ifdef _WIN32
        std::string full_port = "\\\\.\\" + port_name;
        hSerial = CreateFile(full_port.c_str(),
                            GENERIC_READ | GENERIC_WRITE,
                            0,
                            0,
                            OPEN_EXISTING,
                            FILE_ATTRIBUTE_NORMAL,
                            0);
        
        if (hSerial == INVALID_HANDLE_VALUE) {
            log_error("无法打开串口: " + port_name);
            return false;
        }
        
        DCB dcbSerialParams = {0};
        dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
        
        if (!GetCommState(hSerial, &dcbSerialParams)) {
            log_error("获取串口状态失败");
            CloseHandle(hSerial);
            return false;
        }
        
        dcbSerialParams.BaudRate = baud_rate;
        dcbSerialParams.ByteSize = 8;
        dcbSerialParams.StopBits = ONESTOPBIT;
        dcbSerialParams.Parity = NOPARITY;
        
        if (!SetCommState(hSerial, &dcbSerialParams)) {
            log_error("设置串口参数失败");
            CloseHandle(hSerial);
            return false;
        }
        
        COMMTIMEOUTS timeouts = {0};
        timeouts.ReadIntervalTimeout = 50;
        timeouts.ReadTotalTimeoutConstant = 50;
        timeouts.ReadTotalTimeoutMultiplier = 10;
        SetCommTimeouts(hSerial, &timeouts);
        
#else
        serial_fd = open(port_name.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
        if (serial_fd == -1) {
            log_error("无法打开串口: " + port_name);
            return false;
        }
        
        struct termios options;
        tcgetattr(serial_fd, &options);
        
        cfsetispeed(&options, baud_rate);
        cfsetospeed(&options, baud_rate);
        
        options.c_cflag &= ~PARENB;
        options.c_cflag &= ~CSTOPB;
        options.c_cflag &= ~CSIZE;
        options.c_cflag |= CS8;
        options.c_cflag &= ~CRTSCTS;
        options.c_cflag |= CREAD | CLOCAL;
        
        options.c_iflag &= ~(IXON | IXOFF | IXANY);
        options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
        
        options.c_oflag &= ~OPOST;
        
        tcsetattr(serial_fd, TCSANOW, &options);
#endif
        
        is_connected = true;
        log_info("✅ 已连接到 " + port_name + "，波特率 " + std::to_string(baud_rate));
        return true;
    }
    
    std::string send_command(const std::string& command, int delay_ms = 500) {
        if (!is_connected) {
            log_error("串口未连接");
            return "";
        }
        
        auto now = std::chrono::system_clock::now();
        auto now_time = std::chrono::system_clock::to_time_t(now);
        std::stringstream timestamp;
        timestamp << std::put_time(std::localtime(&now_time), "%H:%M:%S");
        
        log_info("[" + timestamp.str() + "] 📤 发送: " + command);
        
        std::string cmd = command + "\r\n";
        
#ifdef _WIN32
        DWORD bytes_written;
        WriteFile(hSerial, cmd.c_str(), cmd.length(), &bytes_written, NULL);
#else
        write(serial_fd, cmd.c_str(), cmd.length());
#endif
        
        std::this_thread::sleep_for(std::chrono::milliseconds(delay_ms));
        
        // 读取响应
        std::string response;
        char buffer[256];
        
#ifdef _WIN32
        DWORD bytes_read;
        while (ReadFile(hSerial, buffer, sizeof(buffer) - 1, &bytes_read, NULL) && bytes_read > 0) {
            buffer[bytes_read] = '\0';
            response += buffer;
            
            std::string line(buffer);
            size_t pos = 0;
            while ((pos = line.find('\n')) != std::string::npos) {
                std::string single_line = line.substr(0, pos);
                line.erase(0, pos + 1);
                
                if (!single_line.empty() && single_line != "\r") {
                    log_info("[" + timestamp.str() + "] 📥 收到: " + single_line);
                    update_state_from_response(single_line, command);
                }
            }
        }
#else
        int bytes_read;
        while ((bytes_read = read(serial_fd, buffer, sizeof(buffer) - 1)) > 0) {
            buffer[bytes_read] = '\0';
            response += buffer;
            
            std::string line(buffer);
            size_t pos = 0;
            while ((pos = line.find('\n')) != std::string::npos) {
                std::string single_line = line.substr(0, pos);
                line.erase(0, pos + 1);
                
                if (!single_line.empty() && single_line != "\r") {
                    log_info("[" + timestamp.str() + "] 📥 收到: " + single_line);
                    update_state_from_response(single_line, command);
                }
            }
        }
#endif
        
        return response;
    }
    
    void basic_functional_test() {
        log_info("\n" + std::string(60, '='));
        log_info("🔧 基础功能测试");
        log_info(std::string(60, '='));
        
        std::vector<std::pair<std::string, std::string>> test_steps = {
            {"1. 显示帮助信息", "HELP"},
            {"2. 查询初始状态", "STATUS"},
            {"3. 打开电源通道1", "POWER 1"},
            {"4. 打开电源通道3", "POWER 3"},
            {"5. 打开电源通道5", "POWER 5"},
            {"6. 查询当前状态", "STATUS"},
            {"7. 切换PC数据通道", "PC"},
            {"8. 查询PC模式状态", "STATUS"},
            {"9. 关闭所有通道", "OFF"},
            {"10. 最终状态确认", "STATUS"}
        };
        
        for (const auto& step : test_steps) {
            log_info("\n" + step.first);
            std::string response = send_command(step.second, 300);
            if (!response.empty()) {
                log_info("  响应: " + response);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(300));
        }
        
        log_info("\n✅ 基础功能测试完成");
    }
    
    void channel_comprehensive_test() {
        log_info("\n" + std::string(60, '='));
        log_info("🧪 通道综合测试");
        log_info(std::string(60, '='));
        
        // 测试所有电源通道
        log_info("\n🔌 测试所有电源通道 (1-8):");
        for (int channel = 1; channel <= 8; channel++) {
            log_info("\n  测试通道 " + std::to_string(channel) + ":");
            std::string response = send_command("POWER " + std::to_string(channel), 200);
            if (!response.empty()) {
                log_info("    响应: " + response);
            }
            std::this_thread::sleep_for(std::chrono::milliseconds(200));
        }
        
        // 查询状态
        send_command("STATUS", 300);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        
        // 随机切换测试
        log_info("\n🎲 随机通道切换测试:");
        std::random_device rd;
        std::mt19937 gen(rd());
        std::uniform_int_distribution<> dis(1, 8);
        
        for (int i = 0; i < 10; i++) {
            int channel = dis(gen);
            log_info("  操作 " + std::to_string(i + 1) + ": POWER " + std::to_string(channel));
            send_command("POWER " + std::to_string(channel), 150);
            std::this_thread::sleep_for(std::chrono::milliseconds(150));
        }
        
        // PC模式测试
        log_info("\n💻 PC数据通道测试:");
        send_command("PC", 300);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        send_command("STATUS", 300);
        std::this_thread::sleep_for(std::chrono::milliseconds(500));
        
        // 关闭所有
        log_info("\n🔚 清理测试:");
        send_command("OFF", 300);
        send_command("STATUS", 300);
        
        log_info("\n✅ 通道综合测试完成");
    }
    
    void log_info(const std::string& message) {
        std::cout << message << std::endl;
        log_to_file("INFO: " + message);
    }
    
    void log_error(const std::string& message) {
        std::cout << "❌ " << message << std::endl;
        log_to_file("ERROR: " + message);
    }
    
    void disconnect() {
        if (is_connected) {
            // 发送关闭命令
            send_command("OFF", 300);
            std::this_thread::sleep_for(std::chrono::milliseconds(500));
            
#ifdef _WIN32
            if (hSerial != INVALID_HANDLE_VALUE) {
                CloseHandle(hSerial);
            }
#else
            if (serial_fd != -1) {
                close(serial_fd);
            }
#endif
            
            is_connected = false;
            log_info("🔌 串口连接已关闭");
        }
    }
};

int main(int argc, char* argv[]) {
    std::string port_name = "COM3";
    int baud_rate = 9600;
    std::string test_type = "basic";
    bool interactive = false;
    
    // 解析命令行参数
    for (int i = 1; i < argc; i++) {
        std::string arg = argv[i];
        if (arg == "--port" && i + 1 < argc) {
            port_name = argv[++i];
        } else if (arg == "--baud" && i + 1 < argc) {
            baud_rate = std::stoi(argv[++i]);
        } else if (arg == "--test" && i + 1 < argc) {
            test_type = argv[++i];
        } else if (arg == "--interactive") {
            interactive = true;
        } else if (arg == "--help") {
            std::cout << R"(
多通道USB控制器测试工具 (C++版本)

用法: usb-controller-tester [选项]

选项:
  --port <端口>      串口端口 (默认: COM3)
  --baud <波特率>    波特率 (默认: 9600)
  --test <类型>      测试类型: basic, channel, boundary, performance, all
  --interactive      交互模式
  --help             显示帮助信息

示例:
  usb-controller-tester --port COM3 --test basic
  usb-controller-tester --port /dev/ttyUSB0 --interactive
  usb-controller-tester --test all
            )" << std::endl;
            return 0;
        }
    }
    
    std::cout << "\n" << std::string(60, '=') << std::endl;
    std::cout << "🚀 多通道USB控制器测试程序 (C++版本)" << std::endl;
    std::cout << std::string(60, '=') << std::endl;
    
    USBController controller(port_name, baud_rate);
    
    if (controller.connect()) {
        try {
            if (interactive) {
                // 交互模式（简化版）
                std::cout << "\n💬 交互模式" << std::endl;
                std::cout << std::string(60, '=') << std::endl;
                std::cout << "\n输入命令 (输入 'quit' 退出):" << std::endl;
                
                std::string command;
                while (true) {
                    std::cout << "\n🔧 USB> ";
                    std::getline(std::cin, command);
                    
                    if (command.empty()) {
                        continue;
                    }
                    
                    if (command == "quit" || command == "exit" || command == "q") {
                        std::cout << "👋 退出交互模式" << std::endl;
                        break;
                    }
                    
                    std::string response = controller.send_command(command, 500);
                    if (!response.empty()) {
                        std::cout << "📥 响应: " << response << std::endl;
                    }
                }
            } else {
                if (test_type == "basic") {
                    controller.basic_functional_test();
                } else if (test_type == "channel") {
                    controller.channel_comprehensive_test();
                } else if (test_type == "all") {
                    controller.basic_functional_test();
                    std::this_thread::sleep_for(std::chrono::seconds(1));
                    controller.channel_comprehensive_test();
                    std::this_thread::sleep_for(std::chrono::seconds(1));
                    std::cout << "\n✅ 所有测试完成" << std::endl;
                } else {
                    std::cout << "⚠️  未知测试类型，运行基础测试" << std::endl;
                    controller.basic_functional_test();
                }
            }
            
            controller.disconnect();
        } catch (const std::exception& e) {
            std::cerr << "❌ 测试过程中出错: " << e.what() << std::endl;
        }
    }
    
    std::cout << "\n🎉 测试程序执行完成" << std::endl;
    std::cout << "📝 详细日志保存在: usb_controller_cpp.log" << std::endl;
    
    return 0;
}