<#
.SYNOPSIS
    Edu health check script
.DESCRIPTION
    Checks health of all infrastructure containers + application services + observability endpoints
.EXAMPLE
    .\scripts\health-check.ps1
#>

$ErrorActionPreference = "Continue"

Write-Host "========================================" -ForegroundColor Cyan
Write-Host "  Edu Health Check" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan
Write-Host ""

# ===== 1. Infrastructure containers =====
Write-Host "[1/3] Infrastructure Containers" -ForegroundColor Yellow

$infraContainers = @(
    @{Name="MySQL";         Container="edu-mysql"},
    @{Name="Redis";         Container="edu-redis"},
    @{Name="Kafka";         Container="edu-kafka"},
    @{Name="Zookeeper";     Container="edu-zookeeper"},
    @{Name="ClickHouse";    Container="edu-clickhouse"},
    @{Name="Debezium";      Container="edu-debezium"},
    @{Name="Neo4j";         Container="edu-neo4j"},
    @{Name="Elasticsearch"; Container="edu-es"},
    @{Name="Jaeger";        Container="edu-jaeger"},
    @{Name="Prometheus";    Container="edu-prometheus"},
    @{Name="Grafana";       Container="edu-grafana"}
)

$infraOk = 0
$infraFail = 0
foreach ($svc in $infraContainers) {
    $running = docker inspect -f '{{.State.Running}}' $svc.Container 2>$null
    if ($running -ne "true") {
        Write-Host "  [FAIL] $($svc.Name) not running" -ForegroundColor Red
        $infraFail++
        continue
    }
    # 条件模板：Health 不存在时返回空字符串，不报错
    $health = docker inspect -f '{{if .State.Health}}{{.State.Health.Status}}{{end}}' $svc.Container 2>$null
    if ($health -eq "healthy") {
        Write-Host "  [OK] $($svc.Name)" -ForegroundColor Green
        $infraOk++
    } else {
        Write-Host "  [WARN] $($svc.Name) (running, no healthcheck)" -ForegroundColor Yellow
        $infraOk++
    }
}

Write-Host ""

# ===== 2. Application services =====
Write-Host "[2/3] Application Services" -ForegroundColor Yellow

$appServices = @(
    @{Name="classes";       Url="http://localhost:3001/healthz"},
    @{Name="iam";           Url="http://localhost:3002/healthz"},
    @{Name="teacher-bff";   Url="http://localhost:3003/healthz"},
    @{Name="core-edu";      Url="http://localhost:3004/healthz"},
    @{Name="content";       Url="http://localhost:3005/healthz"},
    @{Name="data-ana";      Url="http://localhost:3006/healthz"},
    @{Name="msg";           Url="http://localhost:3007/healthz"},
    @{Name="ai";            Url="http://localhost:3008/healthz"},
    @{Name="api-gateway";   Url="http://localhost:8080/healthz"},
    @{Name="push-gateway";  Url="http://localhost:8081/healthz"},
    @{Name="teacher-portal";Url="http://localhost:3000/"}
)

$appOk = 0
$appFail = 0
foreach ($svc in $appServices) {
    try {
        $null = Invoke-RestMethod -Uri $svc.Url -Method Get -TimeoutSec 3 -ErrorAction Stop
        Write-Host "  [OK] $($svc.Name)" -ForegroundColor Green
        $appOk++
    } catch {
        Write-Host "  [FAIL] $($svc.Name)" -ForegroundColor Red
        $appFail++
    }
}

Write-Host ""

# ===== 3. Observability endpoints =====
Write-Host "[3/3] Observability Endpoints" -ForegroundColor Yellow

$obsEndpoints = @(
    @{Name="Prometheus API";   Url="http://localhost:9090/api/v1/query?query=up"},
    @{Name="Jaeger API";       Url="http://localhost:16686/api/services"},
    @{Name="Debezium Connect"; Url="http://localhost:8083/connectors"},
    @{Name="data-ana /metrics";Url="http://localhost:3006/metrics"},
    @{Name="iam /metrics";     Url="http://localhost:3002/metrics"}
)

$obsOk = 0
$obsFail = 0
foreach ($ep in $obsEndpoints) {
    try {
        $null = Invoke-RestMethod -Uri $ep.Url -Method Get -TimeoutSec 3 -ErrorAction Stop
        Write-Host "  [OK] $($ep.Name)" -ForegroundColor Green
        $obsOk++
    } catch {
        Write-Host "  [FAIL] $($ep.Name)" -ForegroundColor Red
        $obsFail++
    }
}

# ===== 4. CDC pipeline status =====
Write-Host ""
Write-Host "[Extra] CDC Pipeline Status" -ForegroundColor Yellow

$connectorStatus = $null
try {
    $connectorStatus = Invoke-RestMethod -Uri "http://localhost:8083/connectors/edu-mysql-source/status" -Method Get -TimeoutSec 3 -ErrorAction Stop
} catch {
    Write-Host "  [FAIL] Debezium connector not registered or error" -ForegroundColor Red
}

if ($connectorStatus) {
    $connectorState = $connectorStatus.connector.state
    $tasks = @($connectorStatus.tasks)
    if ($tasks.Count -gt 0) {
        $taskState = $tasks[0].state
    } else {
        $taskState = "UNKNOWN"
    }
    if ($connectorState -eq "RUNNING" -and $taskState -eq "RUNNING") {
        $color = "Green"
    } else {
        $color = "Yellow"
    }
    Write-Host "  Connector: $connectorState / Task: $taskState" -ForegroundColor $color
}

$chSql = 'SELECT count(*) FROM edu_analytics.student_dashboard_view'
$chOutput = docker exec edu-clickhouse clickhouse-client --user default --password clickhouse -q $chSql 2>&1
$chCount = "$chOutput".Trim()
if ($chCount -match '^\d+$') {
    Write-Host "  ClickHouse student_dashboard_view: $chCount records" -ForegroundColor Green
} else {
    Write-Host "  ClickHouse query failed or empty" -ForegroundColor Yellow
}

# ===== Summary =====
Write-Host ""
Write-Host "========================================" -ForegroundColor Cyan
Write-Host "  Infra: $infraOk/$($infraContainers.Count) | App: $appOk/$($appServices.Count) | Obs: $obsOk/$($obsEndpoints.Count)" -ForegroundColor Cyan
Write-Host "========================================" -ForegroundColor Cyan

if ($infraFail -gt 0 -or $appFail -gt 0 -or $obsFail -gt 0) {
    exit 1
}
