#!/bin/bash

# 压力测试快速启动脚本

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"

# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

function log_info() {
    echo -e "${GREEN}[INFO]${NC} $1"
}

function log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $1"
}

function log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

function show_usage() {
    cat << EOF
压力测试脚本（优化版）

用法:
    $0 [command] [options]

命令:
    data        生成测试数据（使用优化的批量生成）
    test        执行压力测试（支持真实认证）
    monitor     监控系统性能
    clean       清理测试数据
    report      生成压测报告
    all         执行完整流程（生成数据 + 压测 + 报告）

选项:
    数据生成:
      -u, --users NUM         生成用户数量（默认: 1000）
      -l, --listings NUM      生成商品数量（默认: 5000）
      -o, --orders NUM        生成订单数量（默认: 3000）
      --ledger NUM            生成钱包流水数量（默认: 10000）
      --chat-messages NUM     生成聊天消息数量（默认: 5000）
      --use-optimized         使用优化的数据生成脚本（推荐）

    压力测试:
      -c, --concurrency NUM   并发数（默认: 50）
      -d, --duration SEC      测试时长/秒（默认: 60）
      -s, --scenario NAME     测试场景:
                                - realistic: 真实业务场景（默认）
                                - admin: 管理后台场景
                                - listing_only: 仅商品查询
      --gradual               启用梯度压测
      --warmup NUM            预热用户数（默认: 100）
      --use-improved          使用改进的压测工具（支持真实认证）
      --url URL               后端地址（默认: http://localhost:8080）

    通用:
      -h, --help              显示帮助信息

示例:
    # 小规模数据生成（使用优化脚本）
    $0 data --use-optimized

    # 真实场景压测（100个用户token，50并发，持续60秒）
    $0 test --use-improved -c 50 -d 60 -s realistic --warmup 100

    # 管理后台压测
    $0 test --use-improved -c 30 -d 120 -s admin

    # 梯度压测（逐步增加负载）
    $0 test --use-improved --gradual -d 60

    # 执行完整流程（优化版）
    $0 all --use-optimized --use-improved

    # 清理测试数据
    $0 clean

EOF
}

# 默认参数
USERS=1000
LISTINGS=5000
ORDERS=3000
LEDGER=10000
CHAT_MESSAGES=5000
CONCURRENCY=50
DURATION=60
SCENARIO="realistic"
BASE_URL="http://localhost:8080"
USE_OPTIMIZED=false
USE_IMPROVED=true
GRADUAL=false
WARMUP=100

# 解析命令行参数
COMMAND=""
while [[ $# -gt 0 ]]; do
    case $1 in
        data|test|monitor|clean|report|all)
            COMMAND="$1"
            shift
            ;;
        -u|--users)
            USERS="$2"
            shift 2
            ;;
        -l|--listings)
            LISTINGS="$2"
            shift 2
            ;;
        -o|--orders)
            ORDERS="$2"
            shift 2
            ;;
        --ledger)
            LEDGER="$2"
            shift 2
            ;;
        --chat-messages)
            CHAT_MESSAGES="$2"
            shift 2
            ;;
        -c|--concurrency)
            CONCURRENCY="$2"
            shift 2
            ;;
        -d|--duration)
            DURATION="$2"
            shift 2
            ;;
        -s|--scenario)
            SCENARIO="$2"
            shift 2
            ;;
        --url)
            BASE_URL="$2"
            shift 2
            ;;
        --use-optimized)
            USE_OPTIMIZED=true
            shift
            ;;
        --use-improved)
            USE_IMPROVED=true
            shift
            ;;
        --gradual)
            GRADUAL=true
            shift
            ;;
        --warmup)
            WARMUP="$2"
            shift 2
            ;;
        -h|--help)
            show_usage
            exit 0
            ;;
        *)
            log_error "未知参数: $1"
            show_usage
            exit 1
            ;;
    esac
done

if [ -z "$COMMAND" ]; then
    log_error "请指定命令"
    show_usage
    exit 1
fi

# 检查数据库连接
function check_database() {
    log_info "检查数据库连接..."
    if docker exec hfb-mysql mysql -uhfb -psecret -e "SELECT 1" &>/dev/null; then
        log_info "数据库连接正常"
        return 0
    else
        log_error "数据库连接失败，请确保 Docker 容器正在运行"
        log_info "提示: 执行 'docker-compose -f deploy/docker-compose.dev.yml up -d' 启动服务"
        return 1
    fi
}

# 检查后端服务
function check_backend() {
    log_info "检查后端服务..."
    if curl -s "$BASE_URL/health" &>/dev/null; then
        log_info "后端服务正常"
        return 0
    else
        log_warn "后端服务未响应: $BASE_URL"
        log_info "提示: 确保后端服务已启动"
        return 1
    fi
}

# 生成测试数据
function generate_data() {
    log_info "开始生成测试数据..."
    log_info "配置: 用户=$USERS, 商品=$LISTINGS, 订单=$ORDERS, 钱包流水=$LEDGER, 聊天消息=$CHAT_MESSAGES"

    check_database || exit 1

    # 选择使用的SQL脚本
    SQL_FILE="$SCRIPT_DIR/load_test_data.sql"
    if [ "$USE_OPTIMIZED" = true ]; then
        SQL_FILE="$SCRIPT_DIR/load_test_data_optimized.sql"
        log_info "使用优化的数据生成脚本"
    fi

    # 创建临时SQL文件
    TMP_SQL="/tmp/load_test_data_$(date +%s).sql"
    trap 'rm -f "$TMP_SQL"' RETURN

    if [ "$USE_OPTIMIZED" = true ]; then
        cat > "$TMP_SQL" << EOF
-- 优化版数据生成
USE hfb_sys;

-- 调用批量生成存储过程
CALL generate_users_batch($USERS);
CALL generate_listings_batch($LISTINGS);
CALL generate_orders_batch($ORDERS);
CALL generate_wallet_ledger_batch($LEDGER);
CALL generate_chat_data_batch($CHAT_MESSAGES);

-- 显示统计
SELECT '用户数' as item, COUNT(*) as count FROM users
UNION ALL SELECT '游戏账号数', COUNT(*) FROM game_accounts
UNION ALL SELECT '商品数', COUNT(*) FROM rental_listings
UNION ALL SELECT '订单数', COUNT(*) FROM rental_orders
UNION ALL SELECT '钱包流水数', COUNT(*) FROM wallet_ledger
UNION ALL SELECT '聊天会话数', COUNT(*) FROM chat_conversations
UNION ALL SELECT '聊天消息数', COUNT(*) FROM chat_messages;
EOF
    else
        cat > "$TMP_SQL" << EOF
-- 原始版数据生成
USE hfb_sys;

-- 调用存储过程生成数据
CALL generate_users($USERS);
CALL generate_listings($LISTINGS);
CALL generate_orders($ORDERS);
CALL generate_wallet_ledger($LEDGER);

-- 生成聊天会话
INSERT INTO chat_conversations (order_id, type, title, status, last_message_at)
SELECT id, 'order_group', CONCAT('订单', order_no, '群聊'), 'active', created_at
FROM rental_orders
WHERE id <= 1000
ON DUPLICATE KEY UPDATE order_id=order_id;

CALL generate_chat_messages($CHAT_MESSAGES);

-- 显示统计
SELECT '用户数' as item, COUNT(*) as count FROM users
UNION ALL SELECT '游戏账号数', COUNT(*) FROM game_accounts
UNION ALL SELECT '商品数', COUNT(*) FROM rental_listings
UNION ALL SELECT '订单数', COUNT(*) FROM rental_orders
UNION ALL SELECT '钱包流水数', COUNT(*) FROM wallet_ledger
UNION ALL SELECT '聊天会话数', COUNT(*) FROM chat_conversations
UNION ALL SELECT '聊天消息数', COUNT(*) FROM chat_messages;
EOF
    fi

    log_info "执行数据生成..."

    # 先执行基础SQL创建存储过程
    docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < "$SQL_FILE"

    # 执行数据生成
    docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys < "$TMP_SQL"

    rm -f "$TMP_SQL"
    trap - RETURN

    log_info "测试数据生成完成！"
}

# 执行压力测试
function run_stress_test() {
    log_info "开始压力测试..."
    log_info "配置: 场景=$SCENARIO, 并发=$CONCURRENCY, 时长=${DURATION}秒, 目标=$BASE_URL"

    check_backend || log_warn "后端服务未响应，测试可能失败"

    # 编译压测工具
    log_info "编译压测工具..."
    cd "$SCRIPT_DIR"

    go build -o stress_test load_stress.go

    if [ $? -ne 0 ]; then
        log_error "压测工具编译失败"
        return 1
    fi

    # 执行压测
    log_info "开始执行压力测试..."

    if [ "$GRADUAL" = true ]; then
        ./stress_test -url "$BASE_URL" -c "$CONCURRENCY" -d "$DURATION" -s "$SCENARIO" -warmup "$WARMUP" -gradual
    else
        ./stress_test -url "$BASE_URL" -c "$CONCURRENCY" -d "$DURATION" -s "$SCENARIO" -warmup "$WARMUP"
    fi

    log_info "压力测试完成！"
}

# 监控系统性能
function monitor_system() {
    log_info "开始监控系统性能（按 Ctrl+C 停止）..."

    echo ""
    echo "=== Docker 容器资源使用 ==="
    docker stats --no-stream hfb-backend hfb-mysql hfb-redis 2>/dev/null || log_warn "部分容器未运行"

    echo ""
    echo "=== MySQL 连接数 ==="
    docker exec hfb-mysql mysql -uhfb -psecret -e "SHOW STATUS LIKE 'Threads_connected';" 2>/dev/null

    echo ""
    echo "=== MySQL 慢查询统计 ==="
    docker exec hfb-mysql mysql -uhfb -psecret -e "SHOW STATUS LIKE 'Slow_queries';" 2>/dev/null

    echo ""
    echo "=== Redis 信息 ==="
    docker exec hfb-redis redis-cli INFO stats | grep -E "total_connections_received|total_commands_processed|instantaneous_ops_per_sec" 2>/dev/null

    echo ""
    log_info "持续监控请使用: docker stats"
}

# 清理测试数据
function clean_data() {
    log_warn "即将清理所有测试数据，此操作不可恢复！"
    read -p "确认继续？(yes/no): " confirm

    if [ "$confirm" != "yes" ]; then
        log_info "已取消清理操作"
        exit 0
    fi

    check_database || exit 1

    log_info "开始清理测试数据..."

    docker exec -i hfb-mysql mysql -uhfb -psecret hfb_sys << 'EOF'
SET FOREIGN_KEY_CHECKS = 0;

-- 清理测试数据（保留ID < 1000的数据）
DELETE FROM chat_messages WHERE id > 100;
DELETE FROM chat_conversations WHERE id > 100;
DELETE FROM wallet_ledger WHERE id > 100;
DELETE FROM rental_orders WHERE id > 100;
DELETE FROM rental_listings WHERE id > 100;
DELETE FROM game_accounts WHERE id > 100;
DELETE FROM users WHERE id > 1000;

-- 重置自增ID
ALTER TABLE users AUTO_INCREMENT = 1001;
ALTER TABLE game_accounts AUTO_INCREMENT = 101;
ALTER TABLE rental_listings AUTO_INCREMENT = 101;
ALTER TABLE rental_orders AUTO_INCREMENT = 101;
ALTER TABLE wallet_ledger AUTO_INCREMENT = 101;
ALTER TABLE chat_conversations AUTO_INCREMENT = 101;
ALTER TABLE chat_messages AUTO_INCREMENT = 101;

SET FOREIGN_KEY_CHECKS = 1;

-- 显示清理后的统计
SELECT '用户数' as item, COUNT(*) as count FROM users
UNION ALL SELECT '商品数', COUNT(*) FROM rental_listings
UNION ALL SELECT '订单数', COUNT(*) FROM rental_orders
UNION ALL SELECT '钱包流水数', COUNT(*) FROM wallet_ledger;
EOF

    log_info "测试数据清理完成！"
}

# 生成压测报告
function generate_report() {
    log_info "生成压测报告..."

    REPORT_FILE="$PROJECT_ROOT/stress_test_report_$(date +%Y%m%d_%H%M%S).txt"

    {
        echo "==================================="
        echo "压力测试报告"
        echo "生成时间: $(date '+%Y-%m-%d %H:%M:%S')"
        echo "==================================="
        echo ""

        echo "--- 数据库统计 ---"
        docker exec hfb-mysql mysql -uhfb -psecret hfb_sys -e "
            SELECT '用户数' as item, COUNT(*) as count FROM users
            UNION ALL SELECT '商品数', COUNT(*) FROM rental_listings
            UNION ALL SELECT '订单数', COUNT(*) FROM rental_orders
            UNION ALL SELECT '钱包流水', COUNT(*) FROM wallet_ledger;
        " 2>/dev/null

        echo ""
        echo "--- MySQL 性能指标 ---"
        docker exec hfb-mysql mysql -uhfb -psecret -e "
            SHOW STATUS LIKE 'Threads_connected';
            SHOW STATUS LIKE 'Slow_queries';
            SHOW STATUS LIKE 'Questions';
        " 2>/dev/null

        echo ""
        echo "--- 表大小统计 ---"
        docker exec hfb-mysql mysql -uhfb -psecret hfb_sys -e "
            SELECT
                table_name AS '表名',
                ROUND(((data_length + index_length) / 1024 / 1024), 2) AS '大小(MB)',
                table_rows AS '行数'
            FROM information_schema.TABLES
            WHERE table_schema = 'hfb_sys'
            ORDER BY (data_length + index_length) DESC
            LIMIT 10;
        " 2>/dev/null

    } > "$REPORT_FILE"

    cat "$REPORT_FILE"

    log_info "报告已保存到: $REPORT_FILE"
}

# 执行完整流程
function run_all() {
    log_info "执行完整压测流程..."

    generate_data
    sleep 3

    run_stress_test
    sleep 2

    generate_report

    log_info "完整流程执行完成！"
}

# 执行命令
case $COMMAND in
    data)
        generate_data
        ;;
    test)
        run_stress_test
        ;;
    monitor)
        monitor_system
        ;;
    clean)
        clean_data
        ;;
    report)
        generate_report
        ;;
    all)
        run_all
        ;;
    *)
        log_error "未知命令: $COMMAND"
        show_usage
        exit 1
        ;;
esac
