# CE-001: 数据库不可用韧性验证
# 验证：当数据库连接中断时，健康检查正确返回 DOWN，API 返回 503

param(
    [string]$BaseURL = "http://localhost:8080",
    [string]$DBPath = ".\data\user_management.db",
    [int]$TimeoutSeconds = 30
)

$ErrorActionPreference = "Stop"
$passed = 0
$failed = 0

function Write-Pass { param($msg) Write-Host "  ✅ $msg" -ForegroundColor Green; $script:passed++ }
function Write-Fail { param($msg) Write-Host "  ❌ $msg" -ForegroundColor Red; $script:failed++ }
function Write-Step { param($msg) Write-Host "`n[STEP] $msg" -ForegroundColor Cyan }

Write-Host "=== CE-001: 数据库不可用韧性验证 ===" -ForegroundColor Magenta
Write-Host "目标服务: $BaseURL"
Write-Host "数据库路径: $DBPath"
Write-Host ""

# 前置检查：服务必须正常运行
Write-Step "前置检查：验证服务初始状态"
try {
    $health = Invoke-RestMethod -Uri "$BaseURL/health/ready" -TimeoutSec 5
    if ($health.status -eq "UP") {
        Write-Pass "服务初始状态 UP"
    } else {
        Write-Fail "服务初始状态不健康 ($($health.status))，请先启动服务"
        exit 1
    }
} catch {
    Write-Fail "无法连接到服务: $($_.Exception.Message)"
    exit 1
}

# 记录实验前指标
Write-Step "记录实验前基线指标"
try {
    $beforeMetrics = Invoke-RestMethod -Uri "$BaseURL/metrics" -TimeoutSec 5
    Write-Pass "基线指标已记录"
} catch {
    Write-Host "  ℹ️ /metrics 端点未就绪（可能是 P0 修复前状态），跳过指标记录"
}

# 注意：此脚本为"观察模式"，不实际关闭数据库
# 在生产混沌实验中，应使用专用的故障注入工具
Write-Step "故障注入模拟（观察模式）"
Write-Host "  ℹ️ 本实验为观察模式，不实际关闭数据库" -ForegroundColor Yellow
Write-Host "  ℹ️ 生产环境请使用: chaostoolkit / Gremlin / 手动关闭 DB 进程"

# 模拟：快速连续请求，观察健康检查行为
Write-Step "并发健康检查验证"
$jobs = 1..5 | ForEach-Object {
    Start-Job -ScriptBlock {
        param($url)
        try {
            $resp = Invoke-RestMethod -Uri "$url/health/ready" -TimeoutSec 3
            return @{ status = $resp.status; ok = $true }
        } catch {
            return @{ status = "ERROR"; ok = $false; error = $_.Exception.Message }
        }
    } -ArgumentList $BaseURL
}

$results = $jobs | Wait-Job | Receive-Job
$allUp = ($results | Where-Object { $_.status -ne "UP" }).Count -eq 0

if ($allUp) {
    Write-Pass "5次并发健康检查全部返回 UP"
} else {
    Write-Fail "部分健康检查失败: $($results | ConvertTo-Json -Compress)"
}

# 验证健康检查格式是否符合规范
Write-Step "验证健康检查响应格式"
try {
    $health = Invoke-RestMethod -Uri "$BaseURL/health/ready" -TimeoutSec 5
    
    if ($health.status) { Write-Pass "包含 status 字段: $($health.status)" }
    else { Write-Fail "缺少 status 字段" }
    
    if ($health.checks) { Write-Pass "包含 checks 字段" }
    else { Write-Fail "缺少 checks 字段" }
    
    if ($health.timestamp) { Write-Pass "包含 timestamp 字段: $($health.timestamp)" }
    else { Write-Fail "缺少 timestamp 字段（需要升级 health.go）" }
    
    if ($health.checks.database) {
        Write-Pass "database 检查存在: $($health.checks.database.status)"
    } else {
        Write-Fail "缺少 database 检查"
    }
} catch {
    Write-Fail "健康检查请求失败: $($_.Exception.Message)"
}

# 验证 Liveness 端点（应始终返回成功）
Write-Step "验证 Liveness 端点（应始终成功）"
try {
    $resp = Invoke-WebRequest -Uri "$BaseURL/health/live" -TimeoutSec 5
    if ($resp.StatusCode -eq 200 -or $resp.StatusCode -eq 204) {
        Write-Pass "Liveness 检查返回 $($resp.StatusCode)"
    } else {
        Write-Fail "Liveness 检查返回非成功状态: $($resp.StatusCode)"
    }
} catch {
    Write-Fail "Liveness 检查失败: $($_.Exception.Message)"
}

# 汇总
Write-Host "`n=== 实验结果 ===" -ForegroundColor Magenta
Write-Host "通过: $passed"
Write-Host "失败: $failed"

if ($failed -eq 0) {
    Write-Host "`n✅ CE-001 观察阶段通过" -ForegroundColor Green
    Write-Host "⚠️  完整实验需要手动关闭数据库并验证 503 响应" -ForegroundColor Yellow
    exit 0
} else {
    Write-Host "`n❌ CE-001 存在 $failed 个验证失败" -ForegroundColor Red
    exit 1
}
