#!/bin/bash

# USB控制器串口测试脚本

SERIAL_PORT="/dev/ttyUSB0"
BAUD_RATE="9600"
LOG_FILE="usb_controller_test.log"

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_message() {
    local level=$1
    local message=$2
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${message}"
    echo "[${timestamp}] ${level}: ${message}" >> "$LOG_FILE"
}

# 检查串口设备
check_serial_port() {
    if [ ! -e "$SERIAL_PORT" ]; then
        log_message "ERROR" "串口设备 $SERIAL_PORT 不存在"
        echo "可用的串口设备:"
        ls /dev/ttyUSB* /dev/ttyACM* 2>/dev/null || echo "未找到串口设备"
        exit 1
    fi
    
    # 检查权限
    if [ ! -r "$SERIAL_PORT" ] || [ ! -w "$SERIAL_PORT" ]; then
        echo -e "${YELLOW}警告: 可能需要设置串口权限${NC}"
        echo "运行: sudo chmod 666 $SERIAL_PORT"
        read -p "是否尝试设置权限? (y/n): " -n 1 -r
        echo
        if [[ $REPLY =~ ^[Yy]$ ]]; then
            sudo chmod 666 "$SERIAL_PORT" && echo "权限设置成功" || echo "权限设置失败"
        fi
    fi
}

# 发送命令并获取响应（使用stty）
send_command() {
    local command="$1"
    local expected_response="$2"
    
    log_message "SEND" "发送: $command"
    
    # 配置串口
    stty -F "$SERIAL_PORT" "$BAUD_RATE" cs8 -cstopb -parenb raw
    
    # 发送命令
    echo -e "$command\r" > "$SERIAL_PORT"
    
    # 读取响应（超时1秒）
    local response=""
    local timeout=1
    local start_time=$(date +%s)
    
    while true; do
        if read -t 0.1 -r line < "$SERIAL_PORT" 2>/dev/null; then
            response+="$line"
            log_message "RECV" "收到: $line"
        fi
        
        current_time=$(date +%s)
        if (( current_time - start_time >= timeout )); then
            break
        fi
    done
    
    if [ -z "$response" ]; then
        log_message "INFO" "无响应"
    fi
    
    echo "$response"
}

# 等待特定秒数，显示进度
wait_with_progress() {
    local seconds=$1
    local message="${2:-等待}"
    
    echo -ne "${message} ${seconds}秒 ["
    
    for ((i=0; i<seconds; i++)); do
        echo -n "#"
        sleep 1
    done
    
    echo "] 完成"
}

# 主要测试函数
test_all_commands() {
    echo -e "${GREEN}=== USB控制器测试开始 ===${NC}\n"
    
    # 1. 帮助命令
    echo -e "${BLUE}1. 测试 HELP 命令:${NC}"
    send_command "HELP"
    sleep 1
    
    # 2. 基本模式测试
    echo -e "\n${BLUE}2. 测试基本模式切换:${NC}"
    send_command "POWER"
    sleep 1
    send_command "DATA"
    sleep 1
    send_command "OFF"
    sleep 1
    
    # 3. 状态查询
    echo -e "\n${BLUE}3. 测试 STATUS 命令:${NC}"
    send_command "STATUS"
    sleep 1
    
    # 4. TRIGGER命令测试
    echo -e "\n${BLUE}4. 测试 TRIGGER 命令:${NC}"
    local delays=(1 3 5 10)
    for delay in "${delays[@]}"; do
        echo -e "\n${YELLOW}--- 测试 ${delay}秒延迟 ---${NC}"
        send_command "TRIGGER $delay"
        wait_with_progress $delay "等待触发"
        sleep 2  # 额外等待执行时间
        send_command "STATUS"
        sleep 1
    done
    
    # 5. 默认值测试
    echo -e "\n${BLUE}5. 测试 TRIGGER 默认值:${NC}"
    send_command "TRIGGER"
    wait_with_progress 5 "等待默认5秒触发"
    sleep 2
    send_command "STATUS"
    
    # 6. 边界值测试
    echo -e "\n${BLUE}6. 边界值测试:${NC}"
    send_command "TRIGGER 1"
    wait_with_progress 3 "等待1秒延迟"
    
    send_command "TRIGGER 99"
    local wait_time=$(( 99 > 5 ? 5 : 99 ))
    wait_with_progress $wait_time "等待99秒延迟（测试中限制为${wait_time}秒）"
    sleep 2
    
    # 7. 错误命令测试
    echo -e "\n${BLUE}7. 测试错误命令:${NC}"
    send_command "TRIGGER 0"
    send_command "TRIGGER 100"
    send_command "TRIGGER abc"
    send_command "INVALID"
    
    echo -e "\n${GREEN}=== 测试完成 ===${NC}"
    echo "详细日志保存在: $LOG_FILE"
}

# 压力测试
stress_test() {
    local cycles=${1:-20}
    
    echo -e "${GREEN}=== 开始压力测试 ($cycles 个循环) ===${NC}\n"
    
    for ((i=1; i<=cycles; i++)); do
        echo -e "${YELLOW}循环 $i/$cycles${NC}"
        
        send_command "POWER"
        sleep 0.3
        send_command "STATUS"
        sleep 0.3
        send_command "DATA"
        sleep 0.3
        send_command "STATUS"
        sleep 0.3
        
        if (( i % 3 == 0 )); then
            send_command "TRIGGER 2"
            sleep 2.5
        fi
        
        if (( i % 5 == 0 )); then
            send_command "OFF"
            sleep 0.5
        fi
    done
    
    echo -e "\n${GREEN}=== 压力测试完成 ===${NC}"
}

# 交互模式
interactive_mode() {
    echo -e "${GREEN}进入交互模式${NC}"
    echo -e "可用命令: ${YELLOW}HELP, POWER, DATA, TRIGGER [N], OFF, STATUS${NC}"
    echo -e "输入 'quit' 退出，'test' 运行自动测试，'stress' 运行压力测试\n"
    
    while true; do
        read -p "USB> " command
        
        case $command in
            quit|exit)
                echo "退出交互模式"
                break
                ;;
            test)
                test_all_commands
                ;;
            stress)
                stress_test 10
                ;;
            "")
                continue
                ;;
            *)
                send_command "$command"
                ;;
        esac
    done
}

# 显示帮助
show_help() {
    echo -e "${GREEN}USB控制器串口测试工具${NC}"
    echo
    echo "用法: $0 [选项]"
    echo
    echo "选项:"
    echo "  -p, --port <端口>     串口端口 (默认: $SERIAL_PORT)"
    echo "  -b, --baud <波特率>   波特率 (默认: $BAUD_RATE)"
    echo "  -i, --interactive     交互模式"
    echo "  -s, --stress          压力测试模式"
    echo "  -t, --test            自动测试模式 (默认)"
    echo "  -h, --help            显示帮助信息"
    echo
    echo "示例:"
    echo "  $0 --port /dev/ttyUSB0 --test"
    echo "  $0 --interactive"
    echo "  $0 --stress"
}

# 解析命令行参数
parse_args() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -p|--port)
                SERIAL_PORT="$2"
                shift 2
                ;;
            -b|--baud)
                BAUD_RATE="$2"
                shift 2
                ;;
            -i|--interactive)
                MODE="interactive"
                shift
                ;;
            -s|--stress)
                MODE="stress"
                shift
                ;;
            -t|--test)
                MODE="test"
                shift
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                echo "未知参数: $1"
                show_help
                exit 1
                ;;
        esac
    done
}

# 主函数
main() {
    MODE="test"  # 默认模式
    
    parse_args "$@"
    
    # 检查串口
    check_serial_port
    
    # 清空日志文件
    > "$LOG_FILE"
    
    echo -e "${GREEN}USB控制器测试工具${NC}"
    echo -e "串口: ${YELLOW}$SERIAL_PORT${NC}"
    echo -e "波特率: ${YELLOW}$BAUD_RATE${NC}"
    echo
    
    case $MODE in
        interactive)
            interactive_mode
            ;;
        stress)
            stress_test 20
            ;;
        test|*)
            test_all_commands
            ;;
    esac
}

# 运行主函数
main "$@"