import java.io.*;
import java.util.*;
import java.util.concurrent.*;

public class USBHubTester implements SerialPortEventListener {
    private SerialPort serialPort;
    private InputStream inputStream;
    private OutputStream outputStream;
    private final StringBuilder responseBuffer = new StringBuilder();
    private final BlockingQueue<String> responseQueue = new LinkedBlockingQueue<>();
    private final List<TestResult> testResults = new ArrayList<>();
    
    class TestResult {
        Date timestamp;
        String type;
        String message;
        
        TestResult(String type, String message) {
            this.timestamp = new Date();
            this.type = type;
            this.message = message;
        }
    }
    
    public USBHubTester(String portName, int baudRate) throws Exception {
        // 注意：Java需要RXTX或jSerialComm库
        // 这里使用伪代码，实际使用时需要具体库的API
        
        System.out.println("Connecting to " + portName + "...");
        
        // 实际代码会根据使用的串口库有所不同
        // 这里假设使用jSerialComm库
        serialPort = SerialPort.getCommPort(portName);
        serialPort.setBaudRate(baudRate);
        serialPort.setNumDataBits(8);
        serialPort.setNumStopBits(1);
        serialPort.setParity(SerialPort.NO_PARITY);
        serialPort.setComPortTimeouts(
            SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 
            1000, 
            0
        );
        
        if (!serialPort.openPort()) {
            throw new Exception("Failed to open serial port");
        }
        
        inputStream = serialPort.getInputStream();
        outputStream = serialPort.getOutputStream();
        
        serialPort.addDataListener(this);
        
        System.out.println("✅ Connected to " + portName);
        logTest("Connected to " + portName, "SUCCESS");
    }
    
    private void logTest(String message, String type) {
        String timestamp = new Date().toString().split(" ")[3];
        String formattedMessage = "[" + timestamp + "] " + message;
        
        switch (type) {
            case "SUCCESS":
                System.out.println("✅ " + formattedMessage);
                break;
            case "ERROR":
                System.out.println("❌ " + formattedMessage);
                break;
            case "SEND":
                System.out.println("📤 " + formattedMessage);
                break;
            case "RECEIVE":
                System.out.println("📥 " + formattedMessage);
                break;
            default:
                System.out.println("ℹ️  " + formattedMessage);
        }
        
        testResults.add(new TestResult(type, message));
    }
    
    @Override
    public void serialEvent(SerialPortEvent event) {
        if (event.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
            try {
                byte[] buffer = new byte[1024];
                int len = inputStream.read(buffer);
                if (len > 0) {
                    String response = new String(buffer, 0, len);
                    responseQueue.put(response.trim());
                }
            } catch (Exception e) {
                logTest("Error reading response: " + e.getMessage(), "ERROR");
            }
        }
    }
    
    public String sendCommand(String command) {
        logTest("Sending: " + command, "SEND");
        
        try {
            // 清空响应队列
            responseQueue.clear();
            
            // 发送命令
            outputStream.write((command + "\r\n").getBytes());
            outputStream.flush();
            
            // 等待响应
            String response = responseQueue.poll(1, TimeUnit.SECONDS);
            
            if (response != null && !response.isEmpty()) {
                logTest("Response: " + response, "RECEIVE");
                return response;
            } else {
                logTest("No response", "ERROR");
                return null;
            }
        } catch (Exception e) {
            logTest("Error: " + e.getMessage(), "ERROR");
            return null;
        } finally {
            System.out.println("----------------------------------------");
        }
    }
    
    public void runTests() throws InterruptedException {
        logTest("Starting USB Hub tests...", "INFO");
        
        // 基本命令测试
        sendCommand("HELP");
        sendCommand("STATUS");
        
        logTest("Testing POWER mode...", "INFO");
        for (int channel : new int[]{1, 3, 5}) {
            sendCommand("POWER " + channel);
            sendCommand("STATUS");
        }
        
        logTest("Testing DATA mode...", "INFO");
        for (int channel : new int[]{2, 4, 6}) {
            sendCommand("DATA " + channel);
            sendCommand("STATUS");
        }
        
        logTest("Testing boundary channels...", "INFO");
        sendCommand("POWER 1");
        sendCommand("DATA 8");
        
        logTest("Testing OFF command...", "INFO");
        sendCommand("OFF");
        sendCommand("STATUS");
        
        logTest("Testing case-insensitivity...", "INFO");
        sendCommand("help");
        sendCommand("power 7");
        sendCommand("data 1");
        sendCommand("off");
        sendCommand("status");
        
        logTest("Testing mode switching...", "INFO");
        String[] commands = {
            "POWER 1", "DATA 1", "POWER 2", "DATA 2",
            "OFF", "DATA 3", "POWER 4", "OFF"
        };
        
        for (String cmd : commands) {
            sendCommand(cmd);
            sendCommand("STATUS");
            Thread.sleep(200);
        }
        
        logTest("All tests completed", "SUCCESS");
        
        printTestSummary();
    }
    
    private void printTestSummary() {
        System.out.println("\n📊 Test Summary:");
        System.out.println("================");
        
        Map<String, Long> summary = testResults.stream()
            .collect(Collectors.groupingBy(
                r -> r.type, 
                Collectors.counting()
            ));
        
        summary.forEach((type, count) -> {
            System.out.println(type + ": " + count);
        });
    }
    
    public void close() {
        if (serialPort != null && serialPort.isOpen()) {
            serialPort.closePort();
        }
    }
    
    public static void main(String[] args) {
        try {
            USBHubTester tester = new USBHubTester("COM3", 9600);
            
            try {
                tester.runTests();
            } finally {
                tester.close();
            }
        } catch (Exception e) {
            System.err.println("Error: " + e.getMessage());
            e.printStackTrace();
        }
    }
    
    // 串口事件监听接口（需要根据实际库实现）
    public interface SerialPortEventListener {
        void serialEvent(SerialPortEvent event);
    }
    
    // 串口事件类（需要根据实际库实现）
    public static class SerialPortEvent {
        public static final int DATA_AVAILABLE = 1;
        private int eventType;
        
        public int getEventType() {
            return eventType;
        }
    }
    
    // 串口类（需要根据实际库实现）
    public static class SerialPort {
        public static SerialPort getCommPort(String portName) {
            // 返回串口实例
            return new SerialPort();
        }
        
        public boolean openPort() {
            // 打开串口
            return true;
        }
        
        public void setBaudRate(int rate) {}
        public void setNumDataBits(int bits) {}
        public void setNumStopBits(int bits) {}
        public void setParity(int parity) {}
        public void setComPortTimeouts(int mode, int readTimeout, int writeTimeout) {}
        public InputStream getInputStream() { return System.in; }
        public OutputStream getOutputStream() { return System.out; }
        public void addDataListener(SerialPortEventListener listener) {}
        public void closePort() {}
        public boolean isOpen() { return true; }
    }
}