import java.io.*;
import java.util.*;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

public class USBControllerTester {
    private static final int BAUD_RATE = 9600;
    private static final int TIMEOUT = 2000;
    private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
    
    private String portName;
    private boolean monitoring = true;
    private Thread monitorThread;
    
    public USBControllerTester(String portName) {
        this.portName = portName;
    }
    
    public boolean connect() {
        try {
            // Java串口通信需要额外的库，这里使用模拟方式
            // 实际使用时需要导入RXTX或javax.comm库
            System.out.println("连接到 " + portName + "，波特率 " + BAUD_RATE);
            
            // 启动监控线程
            startMonitoring();
            
            return true;
            
        } catch (Exception e) {
            System.err.println("连接失败: " + e.getMessage());
            return false;
        }
    }
    
    private void startMonitoring() {
        monitorThread = new Thread(() -> {
            while (monitoring) {
                try {
                    // 模拟接收数据
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    break;
                }
            }
        });
        monitorThread.start();
    }
    
    public void sendCommand(String command) {
        String timestamp = LocalTime.now().format(TIME_FORMATTER);
        System.out.println("[" + timestamp + "] 发送: " + command);
        
        try {
            // 模拟发送命令
            Thread.sleep(500);
            
            // 模拟响应
            simulateResponse(command);
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    private void simulateResponse(String command) {
        String timestamp = LocalTime.now().format(TIME_FORMATTER);
        String response = "";
        
        if (command.equalsIgnoreCase("HELP")) {
            response = "Commands case-insensitive:\n" +
                      " HELP        - Show command list\n" +
                      " POWER       - Enable USB power only\n" +
                      " DATA        - Enable USB power and data\n" +
                      " TRIGGER N   - Turn off USB output then enable data mode after N seconds delay (default: 5s)\n" +
                      " OFF         - Turn off USB output\n" +
                      " STATUS      - Show current USB configuration status";
        } else if (command.equalsIgnoreCase("POWER")) {
            response = "Power mode";
        } else if (command.equalsIgnoreCase("DATA")) {
            response = "Data mode";
        } else if (command.equalsIgnoreCase("OFF")) {
            response = "Standby mode";
        } else if (command.equalsIgnoreCase("STATUS")) {
            response = "Status: Standby";
        } else if (command.toUpperCase().startsWith("TRIGGER")) {
            String[] parts = command.split(" ");
            if (parts.length == 1) {
                response = "Trigger task added and scheduled to run in 5s.\n" +
                          "Trigger task executed and switching to data mode now.";
            } else if (parts.length == 2) {
                try {
                    int delay = Integer.parseInt(parts[1]);
                    if (delay >= 1 && delay <= 99) {
                        response = "Trigger task added and scheduled to run in " + delay + "s.\n" +
                                  "Trigger task executed and switching to data mode now.";
                    } else {
                        response = "Error: Invalid parameter";
                    }
                } catch (NumberFormatException e) {
                    response = "Error: Invalid parameter";
                }
            }
        } else {
            response = "Error: Unknown command";
        }
        
        System.out.println("[" + timestamp + "] 收到: " + response);
    }
    
    private void waitWithProgress(int seconds, String message) throws InterruptedException {
        System.out.print(message + " " + seconds + "秒 [");
        
        for (int i = 0; i < seconds; i++) {
            System.out.print("#");
            Thread.sleep(1000);
        }
        
        System.out.println("] 完成");
    }
    
    public void testAllCommands() {
        System.out.println("\n=== USB控制器测试开始 ===\n");
        
        try {
            // 1. 帮助命令
            System.out.println("1. 测试 HELP 命令:");
            sendCommand("HELP");
            Thread.sleep(1000);
            
            // 2. 模式切换
            System.out.println("\n2. 测试模式切换:");
            sendCommand("POWER");
            Thread.sleep(1000);
            sendCommand("DATA");
            Thread.sleep(1000);
            sendCommand("OFF");
            Thread.sleep(1000);
            
            // 3. 状态查询
            System.out.println("\n3. 测试 STATUS 命令:");
            sendCommand("STATUS");
            Thread.sleep(1000);
            
            // 4. TRIGGER命令测试
            System.out.println("\n4. 测试 TRIGGER 命令:");
            int[] delays = {1, 3, 5, 10};
            
            for (int delay : delays) {
                System.out.println("\n--- 测试 " + delay + "秒延迟 ---");
                sendCommand("TRIGGER " + delay);
                waitWithProgress(delay, "等待触发");
                Thread.sleep(2000);
                sendCommand("STATUS");
                Thread.sleep(1000);
            }
            
            // 5. 默认值测试
            System.out.println("\n5. 测试 TRIGGER 默认值:");
            sendCommand("TRIGGER");
            waitWithProgress(5, "等待默认延迟");
            Thread.sleep(2000);
            sendCommand("STATUS");
            
            // 6. 边界值测试
            System.out.println("\n6. 边界值测试:");
            sendCommand("TRIGGER 1");
            Thread.sleep(3000);
            sendCommand("TRIGGER 99");
            int waitTime = Math.min(99, 5);
            System.out.println("等待" + waitTime + "秒...");
            waitWithProgress(waitTime, "等待99秒延迟（测试中限制为" + waitTime + "秒）");
            Thread.sleep(2000);
            
            // 7. 错误命令测试
            System.out.println("\n7. 测试错误命令:");
            String[] invalidCommands = {
                "TRIGGER 0",
                "TRIGGER 100",
                "TRIGGER abc",
                "INVALID"
            };
            
            for (String cmd : invalidCommands) {
                sendCommand(cmd);
                Thread.sleep(500);
            }
            
            System.out.println("\n=== 测试完成 ===");
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    public void stressTest(int cycles) {
        System.out.println("\n=== 开始压力测试 (" + cycles + "个循环) ===\n");
        
        long startTime = System.currentTimeMillis();
        
        try {
            for (int i = 0; i < cycles; i++) {
                System.out.println("循环 " + (i + 1) + "/" + cycles);
                
                sendCommand("POWER");
                Thread.sleep(300);
                sendCommand("STATUS");
                Thread.sleep(300);
                sendCommand("DATA");
                Thread.sleep(300);
                sendCommand("STATUS");
                Thread.sleep(300);
                
                if (i % 3 == 0) {
                    sendCommand("TRIGGER 2");
                    Thread.sleep(2500);
                }
                
                if (i % 5 == 0) {
                    sendCommand("OFF");
                    Thread.sleep(500);
                }
            }
            
            long elapsed = System.currentTimeMillis() - startTime;
            System.out.println("\n压力测试完成，用时: " + (elapsed / 1000.0) + "秒");
            
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    public void interactiveMode() {
        System.out.println("\n进入交互模式 (输入 quit 退出)");
        System.out.println("可用命令: HELP, POWER, DATA, TRIGGER [N], OFF, STATUS\n");
        
        Scanner scanner = new Scanner(System.in);
        
        while (true) {
            System.out.print("输入命令: ");
            String command = scanner.nextLine().trim();
            
            if (command.equalsIgnoreCase("quit")) {
                break;
            }
            
            if (!command.isEmpty()) {
                sendCommand(command);
            }
        }
        
        scanner.close();
    }
    
    public void disconnect() {
        monitoring = false;
        
        if (monitorThread != null && monitorThread.isAlive()) {
            try {
                monitorThread.join(1000);
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        }
        
        System.out.println("连接已关闭");
    }
    
    public static void main(String[] args) {
        String portName = "COM3";
        boolean interactive = false;
        boolean stressTest = false;
        boolean fullTest = true;
        
        // 解析命令行参数
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
                case "--port":
                    if (i + 1 < args.length) {
                        portName = args[++i];
                    }
                    break;
                case "--interactive":
                    interactive = true;
                    fullTest = false;
                    break;
                case "--stress":
                    stressTest = true;
                    fullTest = false;
                    break;
                case "--help":
                    printHelp();
                    return;
            }
        }
        
        USBControllerTester tester = new USBControllerTester(portName);
        
        if (tester.connect()) {
            try {
                if (interactive) {
                    tester.interactiveMode();
                } else if (stressTest) {
                    tester.stressTest(10);
                } else if (fullTest) {
                    tester.testAllCommands();
                }
            } finally {
                tester.disconnect();
            }
        }
    }
    
    private static void printHelp() {
        System.out.println("USB控制器串口测试工具");
        System.out.println();
        System.out.println("用法: java USBControllerTester [选项]");
        System.out.println();
        System.out.println("选项:");
        System.out.println("  --port <端口>     串口端口 (默认: COM3)");
        System.out.println("  --interactive     交互模式");
        System.out.println("  --stress          压力测试模式");
        System.out.println("  --help            显示帮助信息");
        System.out.println();
        System.out.println("示例:");
        System.out.println("  java USBControllerTester --port COM3");
        System.out.println("  java USBControllerTester --port /dev/ttyUSB0 --interactive");
        System.out.println("  java USBControllerTester --stress");
    }
}