#!/bin/bash

# 多通道USB控制器测试程序 (Shell/Bash版本)
# 使用前请安装: stty, screen, 或 minicom

set -e

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

# 默认配置
SERIAL_PORT="/dev/ttyUSB0"
BAUD_RATE="9600"
LOG_FILE="usb_controller_shell.log"
TEST_TYPE="basic"
INTERACTIVE=false

# 状态跟踪
declare -a ACTIVE_CHANNELS=()
MODE="standby"
PC_ENABLED=false

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

log_error() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${RED}[$timestamp] ERROR: $1${NC}"
    echo "[$timestamp] ERROR: $1" >> "$LOG_FILE"
}

log_warning() {
    local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
    echo -e "${YELLOW}[$timestamp] WARNING: $1${NC}"
    echo "[$timestamp] WARNING: $1" >> "$LOG_FILE"
}

# 显示帮助
show_help() {
    echo -e "${GREEN}多通道USB控制器测试工具 (Shell/Bash版本)${NC}"
    echo
    echo "用法: $0 [选项]"
    echo
    echo "选项:"
    echo "  -p, --port <端口>     串口端口 (默认: /dev/ttyUSB0)"
    echo "  -b, --baud <波特率>   波特率 (默认: 9600)"
    echo "  -t, --test <类型>     测试类型: basic, channel, boundary, performance, all"
    echo "  -i, --interactive     交互模式"
    echo "  -l, --list-ports      列出可用串口"
    echo "  -h, --help            显示帮助信息"
    echo
    echo "示例:"
    echo "  $0 --port /dev/ttyUSB0 --test basic"
    echo "  $0 --port COM3 --baud 9600 --interactive"
    echo "  $0 --test all"
}

# 列出可用串口
list_serial_ports() {
    echo -e "${CYAN}📋 可用串口:${NC}"
    
    # Linux
    if command -v lsusb &> /dev/null; then
        echo "USB设备:"
        lsusb | grep -i serial | sed 's/^/  /'
    fi
    
    echo -e "\n串口设备:"
    if ls /dev/ttyUSB* 2>/dev/null; then
        ls /dev/ttyUSB* 2>/dev/null | sed 's/^/  /'
    fi
    
    if ls /dev/ttyACM* 2>/dev/null; then
        ls /dev/ttyACM* 2>/dev/null | sed 's/^/  /'
    fi
    
    if ls /dev/ttyS* 2>/dev/null; then
        ls /dev/ttyS* 2>/dev/null | sed 's/^/  /'
    fi
    
    # macOS
    if ls /dev/cu.* 2>/dev/null; then
        ls /dev/cu.* 2>/dev/null | sed 's/^/  /'
    fi
}

# 检查串口权限
check_serial_permission() {
    if [[ ! -e "$SERIAL_PORT" ]]; then
        log_error "串口设备不存在: $SERIAL_PORT"
        list_serial_ports
        exit 1
    fi
    
    if [[ ! -r "$SERIAL_PORT" ]] || [[ ! -w "$SERIAL_PORT" ]]; then
        log_warning "串口权限不足，尝试设置权限..."
        
        if [[ $EUID -eq 0 ]]; then
            chmod 666 "$SERIAL_PORT"
            log_info "权限设置成功"
        else
            log_warning "需要管理员权限，请运行:"
            echo "  sudo chmod 666 $SERIAL_PORT"
            read -p "是否尝试使用sudo? (y/n): " -n 1 -r
            echo
            if [[ $REPLY =~ ^[Yy]$ ]]; then
                sudo chmod 666 "$SERIAL_PORT" && log_info "权限设置成功" || log_error "权限设置失败"
            fi
        fi
    fi
}

# 配置串口
configure_serial() {
    stty -F "$SERIAL_PORT" "$BAUD_RATE" cs8 -cstopb -parenb raw -echo
    log_info "串口配置完成: $SERIAL_PORT @ ${BAUD_RATE}bps"
}

# 发送命令
send_command() {
    local command="$1"
    local delay="${2:-0.5}"
    
    local timestamp=$(date '+%H:%M:%S')
    echo -e "[$timestamp] ${CYAN}📤 发送: $command${NC}"
    echo "[$timestamp] SEND: $command" >> "$LOG_FILE"
    
    # 发送命令
    echo -e "$command\r" > "$SERIAL_PORT"
    
    # 等待响应
    sleep "$delay"
    
    # 读取响应
    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
            line=$(echo "$line" | tr -d '\r')
            if [[ -n "$line" ]]; then
                response+="$line"$'\n'
                echo -e "[$timestamp] ${GREEN}📥 收到: $line${NC}"
                echo "[$timestamp] RECV: $line" >> "$LOG_FILE"
                update_state_from_response "$line" "$command"
            fi
        fi
        
        local current_time=$(date +%s)
        if (( current_time - start_time >= timeout )); then
            break
        fi
    done
    
    if [[ -z "$response" ]]; then
        echo -e "[$timestamp] ${YELLOW}⚠️  无响应${NC}"
    fi
    
    echo "$response"
}

# 更新状态
update_state_from_response() {
    local response="$1"
    local command="$2"
    local response_lower=$(echo "$response" | tr '[:upper:]' '[:lower:]')
    
    if [[ $response_lower == *"standby"* ]]; then
        MODE="standby"
        ACTIVE_CHANNELS=()
        PC_ENABLED=false
        
    elif [[ $response_lower == *"power mode"* ]]; then
        MODE="power"
        
        # 提取通道号
        for ((i=1; i<=8; i++)); do
            if [[ $response_lower == *"channel $i"* ]]; then
                if [[ ! " ${ACTIVE_CHANNELS[@]} " =~ " $i " ]]; then
                    ACTIVE_CHANNELS+=("$i")
                fi
                PC_ENABLED=false
                break
            fi
        done
        
    elif [[ $response_lower == *"pc data mode"* ]] || [[ $response_lower == *"pc mode"* ]]; then
        MODE="pc"
        PC_ENABLED=true
        ACTIVE_CHANNELS=()
    fi
}

# 显示当前状态
show_current_state() {
    echo -e "\n${MAGENTA}📊 当前状态:${NC}"
    echo "  模式: $MODE"
    echo "  激活通道: ${ACTIVE_CHANNELS[*]}"
    echo "  PC模式: $PC_ENABLED"
}

# 基础功能测试
basic_functional_test() {
    echo -e "\n${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}🔧 基础功能测试${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    
    local 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 step in "${test_steps[@]}"; do
        IFS=':' read -r description command <<< "$step"
        echo -e "\n${YELLOW}$description${NC}"
        send_command "$command" 0.3
        sleep 0.3
    done
    
    echo -e "\n${GREEN}✅ 基础功能测试完成${NC}"
}

# 通道综合测试
channel_comprehensive_test() {
    echo -e "\n${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}🧪 通道综合测试${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    
    # 测试所有电源通道
    echo -e "\n${CYAN}🔌 测试所有电源通道 (1-8):${NC}"
    for ((channel=1; channel<=8; channel++)); do
        echo -e "\n  ${YELLOW}测试通道 $channel:${NC}"
        send_command "POWER $channel" 0.2
        sleep 0.2
    done
    
    # 查询状态
    send_command "STATUS" 0.3
    sleep 0.5
    
    # 随机切换测试
    echo -e "\n${CYAN}🎲 随机通道切换测试:${NC}"
    for ((i=0; i<10; i++)); do
        channel=$(( RANDOM % 8 + 1 ))
        echo -e "  ${YELLOW}操作 $((i+1)): POWER $channel${NC}"
        send_command "POWER $channel" 0.15
        sleep 0.15
    done
    
    # PC模式测试
    echo -e "\n${CYAN}💻 PC数据通道测试:${NC}"
    send_command "PC" 0.3
    sleep 0.5
    send_command "STATUS" 0.3
    sleep 0.5
    
    # 关闭所有
    echo -e "\n${CYAN}🔚 清理测试:${NC}"
    send_command "OFF" 0.3
    send_command "STATUS" 0.3
    
    echo -e "\n${GREEN}✅ 通道综合测试完成${NC}"
}

# 性能测试
performance_test() {
    local iterations=${1:-30}
    
    echo -e "\n${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}⚡ 性能测试${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    
    echo -e "\n${CYAN}执行 $iterations 次快速切换测试...${NC}"
    
    local start_time=$(date +%s.%N)
    local successful_commands=0
    local failed_commands=0
    
    for ((i=0; i<iterations; i++)); do
        # 随机选择命令类型
        local command_types=("POWER" "PC" "STATUS" "OFF")
        local command_type=${command_types[$((RANDOM % 4))]}
        
        if [[ $command_type == "POWER" ]]; then
            local channel=$(( RANDOM % 8 + 1 ))
            local command="POWER $channel"
        else
            local command="$command_type"
        fi
        
        # 发送命令
        if send_command "$command" 0.08 > /dev/null; then
            ((successful_commands++))
        else
            ((failed_commands++))
        fi
        
        # 每10次显示进度
        if (( (i + 1) % 10 == 0 )); then
            echo -e "  ${YELLOW}进度: $((i+1))/$iterations${NC}"
        fi
        
        sleep 0.08
    done
    
    local end_time=$(date +%s.%N)
    local total_time=$(echo "$end_time - $start_time" | bc)
    
    # 统计结果
    echo -e "\n${MAGENTA}📊 性能测试结果:${NC}"
    echo "  总时间: $(printf "%.2f" "$total_time")秒"
    echo "  平均响应时间: $(echo "scale=1; $total_time / $iterations * 1000" | bc)毫秒"
    echo "  成功命令: $successful_commands"
    echo "  失败命令: $failed_commands"
    echo "  成功率: $(echo "scale=1; $successful_commands / $iterations * 100" | bc)%"
    
    # 最终状态
    send_command "OFF" 0.3
    send_command "STATUS" 0.3
    
    echo -e "\n${GREEN}✅ 性能测试完成${NC}"
}

# 交互模式
interactive_mode() {
    echo -e "\n${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}💬 交互模式${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    
    local help_text='
可用命令:
  HELP                 - 显示帮助信息
  POWER <1-8>          - 切换指定电源通道
  PC                   - 切换PC数据通道
  OFF                  - 关闭所有通道
  STATUS              - 查询当前状态
  TEST basic          - 运行基础功能测试
  TEST channel        - 运行通道综合测试
  TEST performance    - 运行性能测试
  HISTORY             - 显示命令历史
  STATE              - 显示当前状态
  CLEAR               - 清除屏幕
  QUIT / EXIT         - 退出交互模式
    '
    
    echo -e "${CYAN}$help_text${NC}"
    
    local command_history=()
    
    while true; do
        echo -en "\n${YELLOW}🔧 USB> ${NC}"
        read -r user_input
        
        if [[ -z "$user_input" ]]; then
            continue
        fi
        
        # 添加到历史
        command_history+=("$user_input")
        
        case $(echo "$user_input" | tr '[:lower:]' '[:upper:]') in
            "QUIT"|"EXIT"|"Q")
                echo -e "${GREEN}👋 退出交互模式${NC}"
                break
                ;;
            "HISTORY")
                echo -e "\n${MAGENTA}📜 命令历史:${NC}"
                local start_index=$(( ${#command_history[@]} - 10 ))
                if (( start_index < 0 )); then
                    start_index=0
                fi
                for ((i=start_index; i<${#command_history[@]}; i++)); do
                    echo "  $((i - start_index + 1)). ${command_history[$i]}"
                done
                ;;
            "CLEAR")
                clear
                echo -e "${CYAN}$help_text${NC}"
                ;;
            "STATE")
                show_current_state
                ;;
            *)
                if [[ $user_input =~ ^TEST\ + ]]; then
                    local test_type=$(echo "$user_input" | cut -d' ' -f2)
                    case $test_type in
                        "basic")
                            basic_functional_test
                            ;;
                        "channel")
                            channel_comprehensive_test
                            ;;
                        "performance")
                            performance_test 20
                            ;;
                        *)
                            echo -e "${RED}⚠️  未知测试类型: $test_type${NC}"
                            ;;
                    esac
                else
                    # 发送原始命令
                    local response=$(send_command "$user_input" 0.5)
                    if [[ -z "$response" ]]; then
                        echo -e "${YELLOW}⚠️  无响应${NC}"
                    fi
                fi
                ;;
        esac
    done
}

# 清理函数
cleanup() {
    echo -e "\n${YELLOW}正在清理...${NC}"
    send_command "OFF" 0.3
    echo -e "${GREEN}✅ 清理完成${NC}"
}

# 解析命令行参数
parse_arguments() {
    while [[ $# -gt 0 ]]; do
        case $1 in
            -p|--port)
                SERIAL_PORT="$2"
                shift 2
                ;;
            -b|--baud)
                BAUD_RATE="$2"
                shift 2
                ;;
            -t|--test)
                TEST_TYPE="$2"
                shift 2
                ;;
            -i|--interactive)
                INTERACTIVE=true
                shift
                ;;
            -l|--list-ports)
                list_serial_ports
                exit 0
                ;;
            -h|--help)
                show_help
                exit 0
                ;;
            *)
                echo -e "${RED}未知参数: $1${NC}"
                show_help
                exit 1
                ;;
        esac
    done
}

# 主函数
main() {
    echo -e "\n${GREEN}════════════════════════════════════════════════════════════════${NC}"
    echo -e "${GREEN}🚀 多通道USB控制器测试程序 (Shell/Bash版本)${NC}"
    echo -e "${GREEN}════════════════════════════════════════════════════════════════${NC}"
    
    # 解析参数
    parse_arguments "$@"
    
    # 显示配置
    echo -e "${CYAN}配置信息:${NC}"
    echo "  串口端口: $SERIAL_PORT"
    echo "  波特率: $BAUD_RATE"
    echo "  测试类型: $TEST_TYPE"
    echo "  日志文件: $LOG_FILE"
    
    # 检查串口权限和配置
    check_serial_permission
    configure_serial
    
    # 设置退出时的清理
    trap cleanup EXIT
    
    # 运行测试
    if $INTERACTIVE; then
        interactive_mode
    else
        case $TEST_TYPE in
            "basic")
                basic_functional_test
                ;;
            "channel")
                channel_comprehensive_test
                ;;
            "boundary")
                # 边界测试（简化版）
                echo -e "\n${GREEN}⚠️  边界条件测试${NC}"
                send_command "POWER 1" 0.3
                send_command "POWER 8" 0.3
                send_command "PC" 0.3
                send_command "OFF" 0.3
                echo -e "\n${GREEN}✅ 边界条件测试完成${NC}"
                ;;
            "performance")
                performance_test 50
                ;;
            "all")
                basic_functional_test
                sleep 1
                channel_comprehensive_test
                sleep 1
                performance_test 30
                ;;
            *)
                echo -e "${RED}⚠️  未知测试类型，运行基础测试${NC}"
                basic_functional_test
                ;;
        esac
    fi
    
    echo -e "\n${GREEN}🎉 测试程序执行完成${NC}"
    echo -e "${CYAN}📝 详细日志保存在: $LOG_FILE${NC}"
}

# 运行主函数
main "$@"