#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <termios.h>
#include <time.h>

#define BUF_SIZE 256
#define DEFAULT_PORT "/dev/ttyUSB0"
#define BAUD_RATE B9600

typedef struct {
    int fd;
    char port[64];
} USBHubTester;

// 初始化串口
int usbhub_init(USBHubTester *tester, const char *port) {
    strncpy(tester->port, port, sizeof(tester->port) - 1);
    
    tester->fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
    if (tester->fd == -1) {
        perror("Unable to open serial port");
        return -1;
    }
    
    // 确保设备为非阻塞模式
    fcntl(tester->fd, F_SETFL, 0);
    
    struct termios options;
    tcgetattr(tester->fd, &options);
    
    // 设置波特率
    cfsetispeed(&options, BAUD_RATE);
    cfsetospeed(&options, BAUD_RATE);
    
    // 8位数据，无校验，1位停止位
    options.c_cflag &= ~PARENB;
    options.c_cflag &= ~CSTOPB;
    options.c_cflag &= ~CSIZE;
    options.c_cflag |= CS8;
    options.c_cflag |= (CLOCAL | CREAD);
    
    // 禁用软件流控
    options.c_iflag &= ~(IXON | IXOFF | IXANY);
    options.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);
    
    // 原始输出
    options.c_oflag &= ~OPOST;
    
    // 设置超时：立即返回
    options.c_cc[VMIN] = 0;
    options.c_cc[VTIME] = 1;
    
    tcsetattr(tester->fd, TCSANOW, &options);
    
    printf("Connected to %s\n", port);
    return 0;
}

// 发送命令
void usbhub_send_command(USBHubTester *tester, const char *command) {
    char buffer[BUF_SIZE];
    ssize_t bytes_read;
    
    printf("\nSending: %s\n", command);
    
    // 发送命令
    write(tester->fd, command, strlen(command));
    write(tester->fd, "\r\n", 2);
    
    // 等待响应
    usleep(500000);
    
    // 清空缓冲区
    tcflush(tester->fd, TCIFLUSH);
    
    // 读取响应
    bytes_read = read(tester->fd, buffer, BUF_SIZE - 1);
    if (bytes_read > 0) {
        buffer[bytes_read] = '\0';
        printf("Response: %s", buffer);
    } else {
        printf("No response\n");
    }
    
    printf("----------------------------------------\n");
}

// 运行测试
void usbhub_run_tests(USBHubTester *tester) {
    printf("Starting USB Hub tests...\n");
    
    // 基本命令测试
    usbhub_send_command(tester, "HELP");
    usbhub_send_command(tester, "STATUS");
    
    printf("\nTesting POWER mode:\n");
    for (int channel = 1; channel <= 5; channel += 2) {
        char cmd[20];
        snprintf(cmd, sizeof(cmd), "POWER %d", channel);
        usbhub_send_command(tester, cmd);
        usbhub_send_command(tester, "STATUS");
    }
    
    printf("\nTesting DATA mode:\n");
    for (int channel = 2; channel <= 6; channel += 2) {
        char cmd[20];
        snprintf(cmd, sizeof(cmd), "DATA %d", channel);
        usbhub_send_command(tester, cmd);
        usbhub_send_command(tester, "STATUS");
    }
    
    printf("\nTesting boundary channels:\n");
    usbhub_send_command(tester, "POWER 1");
    usbhub_send_command(tester, "DATA 8");
    
    printf("\nTesting OFF command:\n");
    usbhub_send_command(tester, "OFF");
    usbhub_send_command(tester, "STATUS");
    
    printf("\nTesting case-insensitivity:\n");
    usbhub_send_command(tester, "help");
    usbhub_send_command(tester, "power 7");
    usbhub_send_command(tester, "data 1");
    usbhub_send_command(tester, "status");
    
    printf("\nTesting mode switching:\n");
    const char *commands[] = {
        "POWER 1", "DATA 1", "POWER 2", "DATA 2",
        "OFF", "DATA 3", "POWER 4", "OFF", NULL
    };
    
    for (int i = 0; commands[i] != NULL; i++) {
        usbhub_send_command(tester, commands[i]);
        usbhub_send_command(tester, "STATUS");
        usleep(200000);
    }
    
    printf("\nTests completed\n");
}

// 关闭串口
void usbhub_close(USBHubTester *tester) {
    if (tester->fd != -1) {
        close(tester->fd);
        tester->fd = -1;
    }
}

int main(int argc, char *argv[]) {
    USBHubTester tester = { .fd = -1 };
    const char *port = (argc > 1) ? argv[1] : DEFAULT_PORT;
    
    if (usbhub_init(&tester, port) < 0) {
        return 1;
    }
    
    usbhub_run_tests(&tester);
    usbhub_close(&tester);
    
    return 0;
}