#!/bin/bash

# 用户管理系统自动化测试脚本
# 用途：全面测试所有功能和接口

BASE_URL="http://localhost:8080"
ADMIN_TOKEN=""
USER_TOKEN=""
USER_ID=""
TEST_ADMIN_ACCOUNT="${TEST_ADMIN_ACCOUNT:-admin}"
TEST_ADMIN_PASSWORD="${TEST_ADMIN_PASSWORD:-}"

if [ -z "${TEST_ADMIN_PASSWORD}" ]; then
    echo "请先设置 TEST_ADMIN_PASSWORD"
    exit 1
fi

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

# 打印函数
print_success() {
    echo -e "${GREEN}✓ $1${NC}"
}

print_error() {
    echo -e "${RED}✗ $1${NC}"
}

print_info() {
    echo -e "${YELLOW}➤ $1${NC}"
}

# 测试1：健康检查
test_health_check() {
    print_info "测试1：健康检查"
    response=$(curl -s -w "\n%{http_code}" "${BASE_URL}/health")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "健康检查通过 (200)"
        echo "响应: $body"
    else
        print_error "健康检查失败 (HTTP $http_code)"
    fi
    echo ""
}

# 测试2：用户注册
test_register() {
    print_info "测试2：用户注册"
    
    # 测试正常注册
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/register" \
        -H "Content-Type: application/json" \
        -d '{"username":"testuser1","password":"Test123456","email":"test1@example.com"}')
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "用户注册成功"
        USER_ID=$(echo "$body" | grep -o '"id":[0-9]*' | head -1 | cut -d':' -f2)
        echo "用户ID: $USER_ID"
    else
        print_error "用户注册失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
    
    # 测试重复用户名
    print_info "测试2.1：重复用户名注册"
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/register" \
        -H "Content-Type: application/json" \
        -d '{"username":"testuser1","password":"Test123456","email":"test2@example.com"}')
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "400" ] || [ "$http_code" = "409" ]; then
        print_success "重复用户名注册被正确拒绝 ($http_code)"
    else
        print_error "重复用户名验证失败 (HTTP $http_code)"
    fi
    echo ""
    
    # 测试弱密码
    print_info "测试2.2：弱密码注册"
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/register" \
        -H "Content-Type: application/json" \
        -d '{"username":"testuser2","password":"123","email":"test2@example.com"}')
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "400" ]; then
        print_success "弱密码注册被正确拒绝 (400)"
    else
        print_error "弱密码验证失败 (HTTP $http_code)"
    fi
    echo ""
    
    # 测试无效邮箱
    print_info "测试2.3：无效邮箱注册"
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/register" \
        -H "Content-Type: application/json" \
        -d '{"username":"testuser3","password":"Test123456","email":"invalid"}')
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "400" ]; then
        print_success "无效邮箱注册被正确拒绝 (400)"
    else
        print_error "邮箱验证失败 (HTTP $http_code)"
    fi
    echo ""
}

# 测试3：用户登录
test_login() {
    print_info "测试3：用户登录"
    
    # 测试正常登录（管理员）
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/login" \
        -H "Content-Type: application/json" \
        -d "{\"account\":\"${TEST_ADMIN_ACCOUNT}\",\"password\":\"${TEST_ADMIN_PASSWORD}\"}")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "管理员登录成功"
        ADMIN_TOKEN=$(echo "$body" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
        echo "获取到访问令牌"
    else
        print_error "管理员登录失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
    
    # 测试错误密码
    print_info "测试3.1：错误密码登录"
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/login" \
        -H "Content-Type: application/json" \
        -d '{"account":"admin","password":"wrong"}')
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "401" ]; then
        print_success "错误密码登录被正确拒绝 (401)"
    else
        print_error "错误密码验证失败 (HTTP $http_code)"
    fi
    echo ""
    
    # 测试用户名登录
    if [ -n "$USER_ID" ]; then
        print_info "测试3.2：用户名登录（新注册用户）"
        response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/login" \
            -H "Content-Type: application/json" \
            -d '{"account":"testuser1","password":"Test123456"}')
        http_code=$(echo "$response" | tail -n1)
        body=$(echo "$response" | sed '$d')
        
        if [ "$http_code" = "200" ]; then
            print_success "新用户登录成功"
            USER_TOKEN=$(echo "$body" | grep -o '"access_token":"[^"]*' | cut -d'"' -f4)
        else
            print_error "新用户登录失败 (HTTP $http_code)"
        fi
        echo ""
    fi
}

# 测试4：获取用户信息
test_get_userinfo() {
    print_info "测试4：获取用户信息（需要认证）"
    
    if [ -z "$ADMIN_TOKEN" ]; then
        print_error "没有访问令牌，跳过测试"
        return
    fi
    
    response=$(curl -s -w "\n%{http_code}" -X GET "${BASE_URL}/api/v1/auth/userinfo" \
        -H "Authorization: Bearer ${ADMIN_TOKEN}")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "获取用户信息成功"
        echo "响应: $body"
    else
        print_error "获取用户信息失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
    
    # 测试无令牌访问
    print_info "测试4.1：无令牌访问"
    response=$(curl -s -w "\n%{http_code}" -X GET "${BASE_URL}/api/v1/auth/userinfo")
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "401" ]; then
        print_success "无令牌访问被正确拒绝 (401)"
    else
        print_error "认证验证失败 (HTTP $http_code)"
    fi
    echo ""
    
    # 测试无效令牌
    print_info "测试4.2：无效令牌访问"
    response=$(curl -s -w "\n%{http_code}" -X GET "${BASE_URL}/api/v1/auth/userinfo" \
        -H "Authorization: Bearer invalid_token")
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "401" ]; then
        print_success "无效令牌访问被正确拒绝 (401)"
    else
        print_error "无效令牌验证失败 (HTTP $http_code)"
    fi
    echo ""
}

# 测试5：获取用户列表
test_get_users() {
    print_info "测试5：获取用户列表（需要认证）"
    
    if [ -z "$ADMIN_TOKEN" ]; then
        print_error "没有访问令牌，跳过测试"
        return
    fi
    
    response=$(curl -s -w "\n%{http_code}" -X GET "${BASE_URL}/api/v1/users" \
        -H "Authorization: Bearer ${ADMIN_TOKEN}")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "获取用户列表成功"
        echo "响应: $body"
    else
        print_error "获取用户列表失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
}

# 测试6：更新用户信息
test_update_user() {
    print_info "测试6：更新用户信息（需要认证）"
    
    if [ -z "$ADMIN_TOKEN" ] || [ -z "$USER_ID" ]; then
        print_error "缺少必要参数，跳过测试"
        return
    fi
    
    response=$(curl -s -w "\n%{http_code}" -X PUT "${BASE_URL}/api/v1/users/${USER_ID}" \
        -H "Authorization: Bearer ${ADMIN_TOKEN}" \
        -H "Content-Type: application/json" \
        -d '{"nickname":"测试用户昵称","bio":"这是个人简介"}')
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "更新用户信息成功"
        echo "响应: $body"
    else
        print_error "更新用户信息失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
}

# 测试7：令牌刷新
test_refresh_token() {
    print_info "测试7：令牌刷新"
    
    if [ -z "$ADMIN_TOKEN" ]; then
        print_error "没有访问令牌，跳过测试"
        return
    fi
    
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/refresh" \
        -H "Content-Type: application/json" \
        -d "{\"refresh_token\":\"${ADMIN_TOKEN}\"}")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ] || [ "$http_code" = "401" ]; then
        print_success "令牌刷新接口响应正常 (HTTP $http_code)"
        echo "响应: $body"
    else
        print_error "令牌刷新失败 (HTTP $http_code)"
        echo "响应: $body"
    fi
    echo ""
}

# 测试8：限流测试
test_rate_limit() {
    print_info "测试8：限流功能测试"
    
    print_info "快速发送6次请求测试限流..."
    success_count=0
    rate_limited=0
    
    for i in {1..6}; do
        response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/login" \
            -H "Content-Type: application/json" \
            -d '{"account":"wrong","password":"wrong"}')
        http_code=$(echo "$response" | tail -n1)
        
        if [ "$http_code" = "429" ]; then
            rate_limited=$((rate_limited + 1))
            echo "  请求 $i: 被限流 (429)"
        else
            success_count=$((success_count + 1))
            echo "  请求 $i: 正常 (HTTP $http_code)"
        fi
    done
    
    if [ "$rate_limited" -gt 0 ]; then
        print_success "限流功能正常生效，触发 $rate_limited 次限流"
    else
        print_error "限流功能未触发，建议检查配置"
    fi
    echo ""
}

# 测试9：Prometheus 指标
test_metrics() {
    print_info "测试9：Prometheus 指标采集"
    
    response=$(curl -s -w "\n%{http_code}" "${BASE_URL}/metrics")
    http_code=$(echo "$response" | tail -n1)
    body=$(echo "$response" | sed '$d')
    
    if [ "$http_code" = "200" ]; then
        print_success "Prometheus 指标端点正常"
        
        # 检查关键指标
        if echo "$body" | grep -q "http_requests_total"; then
            print_success "✓ http_requests_total 指标存在"
        fi
        if echo "$body" | grep -q "http_request_duration_seconds"; then
            print_success "✓ http_request_duration_seconds 指标存在"
        fi
        if echo "$body" | grep -q "user_logins_total"; then
            print_success "✓ user_logins_total 指标存在"
        fi
    else
        print_error "Prometheus 指标端点失败 (HTTP $http_code)"
    fi
    echo ""
}

# 测试10：登出
test_logout() {
    print_info "测试10：用户登出"
    
    if [ -z "$ADMIN_TOKEN" ]; then
        print_error "没有访问令牌，跳过测试"
        return
    fi
    
    response=$(curl -s -w "\n%{http_code}" -X POST "${BASE_URL}/api/v1/auth/logout" \
        -H "Authorization: Bearer ${ADMIN_TOKEN}")
    http_code=$(echo "$response" | tail -n1)
    
    if [ "$http_code" = "200" ]; then
        print_success "登出成功"
    else
        print_error "登出失败 (HTTP $http_code)"
    fi
    echo ""
}

# 主测试流程
main() {
    echo "============================================"
    echo "   用户管理系统自动化测试"
    echo "   测试环境: ${BASE_URL}"
    echo "============================================"
    echo ""
    
    test_health_check
    test_register
    test_login
    test_get_userinfo
    test_get_users
    test_update_user
    test_refresh_token
    test_rate_limit
    test_metrics
    test_logout
    
    echo "============================================"
    echo "   测试完成"
    echo "============================================"
}

# 执行测试
main
