[CmdletBinding()]
param(
    [string]$DistPath = (Join-Path (Resolve-Path (Join-Path $PSScriptRoot "..")) "dist\ProcessMonitor")
)

$ErrorActionPreference = "Stop"
$dist = (Resolve-Path $DistPath).Path
$guiExe = Join-Path $dist "ProcessMonitor.exe"
$relayExe = Join-Path $dist "ProcessMonitorRelay.exe"
if (-not (Test-Path -LiteralPath $guiExe -PathType Leaf)) { throw "Missing $guiExe" }
if (-not (Test-Path -LiteralPath $relayExe -PathType Leaf)) { throw "Missing $relayExe" }

$smokeRoot = Join-Path ([IO.Path]::GetTempPath()) ("ProcessMonitorFrozenSmoke-" + [guid]::NewGuid().ToString("N"))
$runtimeDir = Join-Path $smokeRoot "relay_runtime"
$configPath = Join-Path $smokeRoot "config.json"
$jsonlPath = Join-Path $smokeRoot "events.jsonl"
$databasePath = Join-Path $smokeRoot "events.db"
New-Item -ItemType Directory -Force -Path $smokeRoot | Out-Null

$config = @{
    Enabled = $true
    AllowList = @()
    WatchList = @()
    AlertRules = @{ HighRiskKeywords = @(); CommandLineIndicators = @(); ParentChildRules = @() }
    Telemetry = @{
        Path = $jsonlPath
        DatabasePath = $databasePath
        PollIntervalSeconds = 1
        HeartbeatIntervalSeconds = 5
        RetentionDays = 14
    }
}
$configJson = $config | ConvertTo-Json -Depth 8
[IO.File]::WriteAllText($configPath, $configJson, [Text.UTF8Encoding]::new($false))
$env:PROCESSMONITOR_DATA_ROOT = $smokeRoot
$env:PROCESSMONITOR_CONFIG = $configPath

try {
    $initial = (& $relayExe --status --config $configPath --runtime-dir $runtimeDir | ConvertFrom-Json)
    if ($initial.running) { throw "Isolated relay unexpectedly started before the test." }

    $started = (& $relayExe --start --config $configPath --runtime-dir $runtimeDir | ConvertFrom-Json)
    if (-not $started.running) { throw "Frozen relay did not start." }
    $workerPid = [int]$started.pid
    Start-Sleep -Milliseconds 500

    $status = (& $relayExe --status --config $configPath --runtime-dir $runtimeDir | ConvertFrom-Json)
    if (-not $status.running -or [int]$status.pid -ne $workerPid) { throw "Frozen relay did not persist." }
    $duplicate = (& $relayExe --start --config $configPath --runtime-dir $runtimeDir | ConvertFrom-Json)
    if ([int]$duplicate.pid -ne $workerPid) { throw "Duplicate start created another worker." }

    $stopped = (& $relayExe --stop --config $configPath --runtime-dir $runtimeDir | ConvertFrom-Json)
    if ($stopped.running) { throw "Frozen relay did not stop." }
    if (Get-Process -Id $workerPid -ErrorAction SilentlyContinue) { throw "Frozen relay worker was orphaned." }

    $env:PROCESSMONITOR_GUI_SMOKE_MS = "3000"
    $guiResizeEvidence = Join-Path $smokeRoot "gui_resize.json"
    $env:PROCESSMONITOR_GUI_RESIZE_SMOKE = $guiResizeEvidence
    $gui = Start-Process -FilePath $guiExe -WindowStyle Hidden -PassThru
    $null = $gui.WaitForExit(15000)
    Start-Sleep -Seconds 2
    if (Get-Process -Name "ProcessMonitor" -ErrorAction SilentlyContinue | Where-Object { $_.Path -eq $guiExe }) {
        throw "Frozen GUI smoke left an orphan process."
    }
    if (-not (Test-Path -LiteralPath $guiResizeEvidence)) { throw "Frozen GUI did not produce resize evidence." }
    $resize = Get-Content -Raw -LiteralPath $guiResizeEvidence | ConvertFrom-Json
    if ($resize.error) { throw "Frozen GUI resize failed: $($resize.error)" }
    if (@($resize.sizes).Count -ne 5 -or @($resize.pages).Count -lt 7) { throw "Frozen GUI resize/page coverage was incomplete." }
    if ($resize.maximized -ne "zoomed" -or $resize.restored -ne "normal") { throw "Frozen GUI maximize/restore failed." }

    Write-Host "Frozen GUI resize/maximize/restore and relay lifecycle smoke: PASS"
}
finally {
    try { & $relayExe --stop --config $configPath --runtime-dir $runtimeDir | Out-Null } catch {}
    Get-Process -Name "ProcessMonitor" -ErrorAction SilentlyContinue |
        Where-Object { $_.Path -eq $guiExe } | Stop-Process -Force -ErrorAction SilentlyContinue
    Remove-Item Env:PROCESSMONITOR_DATA_ROOT -ErrorAction SilentlyContinue
    Remove-Item Env:PROCESSMONITOR_CONFIG -ErrorAction SilentlyContinue
    Remove-Item Env:PROCESSMONITOR_GUI_SMOKE_MS -ErrorAction SilentlyContinue
    Remove-Item Env:PROCESSMONITOR_GUI_RESIZE_SMOKE -ErrorAction SilentlyContinue
    $resolvedSmoke = [IO.Path]::GetFullPath($smokeRoot)
    $resolvedTemp = [IO.Path]::GetFullPath([IO.Path]::GetTempPath())
    if ($resolvedSmoke.StartsWith($resolvedTemp, [StringComparison]::OrdinalIgnoreCase)) {
        Remove-Item -LiteralPath $resolvedSmoke -Recurse -Force -ErrorAction SilentlyContinue
    }
}
