# AetherForge - full test suite runner
param(
    [switch]$SkipE2E,
    [switch]$SkipBuild,
    [switch]$Verbose
)

$ErrorActionPreference = "Stop"
$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
if (-not (Test-Path (Join-Path $Root "server\go.mod"))) {
    $Root = Split-Path -Parent $MyInvocation.MyCommand.Path
    if (-not (Test-Path (Join-Path $Root "server\go.mod"))) {
        $Root = (Get-Location).Path
    }
}

$Results = @()
$Failed = 0

function Write-Phase([string]$Name) {
    Write-Host ""
    Write-Host "==============================================================" -ForegroundColor Cyan
    Write-Host "  $Name" -ForegroundColor Cyan
    Write-Host "==============================================================" -ForegroundColor Cyan
}

function Invoke-Phase([string]$Name, [scriptblock]$Block) {
    Write-Phase $Name
    try {
        & $Block
        if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) { throw "exit code $LASTEXITCODE" }
        $script:Results += [pscustomobject]@{ Phase = $Name; Status = "PASS" }
        Write-Host "  >> PASS" -ForegroundColor Green
    } catch {
        $script:Failed++
        $msg = $_.Exception.Message
        $script:Results += [pscustomobject]@{ Phase = $Name; Status = "FAIL"; Detail = $msg }
        Write-Host "  >> FAIL: $msg" -ForegroundColor Red
        if ($Verbose) { Write-Host $_ }
    }
}

Write-Host ""
Write-Host "  AetherForge Full Test Suite" -ForegroundColor Yellow
Write-Host "  Root: $Root"

Invoke-Phase "1/8 Go server tests" {
    Push-Location (Join-Path $Root "server")
    go test ./... -count=1
    Pop-Location
}

Invoke-Phase "2/8 Go agent tests" {
    Push-Location (Join-Path $Root "agent")
    go test ./... -count=1
    Pop-Location
}

Invoke-Phase "3/8 Fusion module build" {
    Push-Location (Join-Path $Root "fusion")
    go build .
    Pop-Location
}

Invoke-Phase "4/8 Frontend unit tests (Vitest)" {
    Push-Location (Join-Path $Root "server\web")
    if (-not (Test-Path "node_modules")) { npm install --silent }
    npm test
    Pop-Location
}

if (-not $SkipBuild) {
    Invoke-Phase "5/8 Frontend production build" {
        Push-Location (Join-Path $Root "server\web")
        npm run build
        Pop-Location
    }

    Invoke-Phase "6/8 Server binary compile" {
        Push-Location (Join-Path $Root "server")
        go build -o (Join-Path $Root "bin\miner-server.exe") .
        Pop-Location
    }

    Invoke-Phase "7/8 Agent binary compile" {
        Push-Location (Join-Path $Root "agent")
        go build -o (Join-Path $Root "bin\install-worker.exe") .
        Pop-Location
    }

    Invoke-Phase "7b Agent cross-compile (linux/darwin)" {
        Push-Location (Join-Path $Root "agent")
        $env:CGO_ENABLED = "0"
        $env:GOOS = "linux"; $env:GOARCH = "amd64"
        go build -o (Join-Path $Root "bin\install-worker-linux-amd64") -ldflags "-s -w" .
        $env:GOOS = "linux"; $env:GOARCH = "arm64"
        go build -o (Join-Path $Root "bin\install-worker-linux-arm64") -ldflags "-s -w" .
        $env:GOOS = "darwin"; $env:GOARCH = "arm64"
        go build -o (Join-Path $Root "bin\install-worker-darwin-arm64") -ldflags "-s -w" .
        $env:GOOS = "darwin"; $env:GOARCH = "amd64"
        go build -o (Join-Path $Root "bin\install-worker-darwin-amd64") -ldflags "-s -w" .
        Remove-Item Env:GOOS, Env:GOARCH -ErrorAction SilentlyContinue
        Pop-Location
    }

} else {
    Write-Phase "5-7/8 Build phases (skipped)"
}

if (-not $SkipE2E) {
    Invoke-Phase "8/8 E2E smoke (Playwright)" {
        $DataDir = Join-Path $env:TEMP ("aether-e2e-" + [guid]::NewGuid().ToString("n"))
        New-Item -ItemType Directory -Force -Path $DataDir | Out-Null
        $E2EUser = if ($env:AETHERFORGE_E2E_USER) { $env:AETHERFORGE_E2E_USER } else { "testuser" }
        $E2EPass = if ($env:AETHERFORGE_E2E_PASS) { $env:AETHERFORGE_E2E_PASS } else { "testpass" }
        $usersObj = @{ $E2EUser = $E2EPass }
        [System.IO.File]::WriteAllText((Join-Path $DataDir "users.json"), ($usersObj | ConvertTo-Json -Compress))
        $env:AETHERFORGE_E2E_USER = $E2EUser
        $env:AETHERFORGE_E2E_PASS = $E2EPass
        $WebRoot = Join-Path $Root "server\webroot"
        Copy-Item (Join-Path $Root "server\web\dist\*") $WebRoot -Recurse -Force -ErrorAction SilentlyContinue
        $ServerExe = Join-Path $Root "bin\miner-server.exe"
        if (-not (Test-Path $ServerExe)) {
            Push-Location (Join-Path $Root "server")
            go build -o $ServerExe .
            Pop-Location
        }
        $proc = Start-Process -FilePath $ServerExe -ArgumentList "-port","18989","-data",$DataDir -WorkingDirectory $Root -PassThru -WindowStyle Hidden
        try {
            $ready = $false
            for ($i = 0; $i -lt 30; $i++) {
                try {
                    $r = Invoke-RestMethod "http://127.0.0.1:18989/api/v1/health" -TimeoutSec 2
                    if ($r.status -eq "ok") { $ready = $true; break }
                } catch {}
                Start-Sleep -Seconds 1
            }
            if (-not $ready) { throw "E2E server did not become healthy on :18989" }
            Push-Location (Join-Path $Root "server\web")
            $env:AETHERFORGE_URL = "http://127.0.0.1:18989"
            npx playwright install chromium 2>$null | Out-Null
            npx playwright test --config playwright.config.ts
            Pop-Location
        } finally {
            if ($proc -and -not $proc.HasExited) {
                Stop-Process -Id $proc.Id -Force -ErrorAction SilentlyContinue
            }
            Remove-Item $DataDir -Recurse -Force -ErrorAction SilentlyContinue
        }
    }
} else {
    Write-Phase "8/8 E2E (skipped)"
}

Write-Host ""
Write-Host "==============================================================" -ForegroundColor Cyan
Write-Host "  SUMMARY" -ForegroundColor Cyan
Write-Host "==============================================================" -ForegroundColor Cyan
$Results | Format-Table -AutoSize
if ($Failed -gt 0) {
    Write-Host "  $Failed phase(s) FAILED" -ForegroundColor Red
    exit 1
}
Write-Host "  All phases PASSED" -ForegroundColor Green
exit 0
