# Restart the WLED Screen Controller server
# Uses graceful shutdown first (lets the server persist data to disk),
# then force-kills as a fallback.

$serverRoot = 'c:\Users\Alexei\Documents\wled-screen-controller\server'

# Read API key from config for authenticated shutdown request
$configPath = Join-Path $serverRoot 'config\default_config.yaml'
$apiKey = $null
if (Test-Path $configPath) {
    $inKeys = $false
    foreach ($line in Get-Content $configPath) {
        if ($line -match '^\s*api_keys:') { $inKeys = $true; continue }
        if ($inKeys -and $line -match '^\s+\w+:\s*"(.+)"') {
            $apiKey = $Matches[1]; break
        }
        if ($inKeys -and $line -match '^\S') { break }  # left the api_keys block
    }
}

# Find running server processes
$procs = Get-CimInstance Win32_Process -Filter "Name='python.exe'" |
    Where-Object { $_.CommandLine -like '*wled_controller*' -and $_.CommandLine -notlike '*demo*' -and $_.CommandLine -notlike '*vscode*' -and $_.CommandLine -notlike '*isort*' }

if ($procs) {
    # Step 1: Request graceful shutdown via API (triggers lifespan shutdown + store save)
    $shutdownOk = $false
    if ($apiKey) {
        Write-Host "Requesting graceful shutdown..."
        try {
            $headers = @{ Authorization = "Bearer $apiKey" }
            Invoke-RestMethod -Uri 'http://localhost:8080/api/v1/system/shutdown' `
                -Method Post -Headers $headers -TimeoutSec 5 -ErrorAction Stop | Out-Null
            $shutdownOk = $true
        } catch {
            Write-Host "  API shutdown failed ($($_.Exception.Message)), falling back to process kill"
        }
    }

    if ($shutdownOk) {
        # Step 2: Wait for the server to exit gracefully (up to 15 seconds)
        # The server needs time to stop processors, disconnect devices, and persist stores.
        Write-Host "Waiting for graceful shutdown..."
        $waited = 0
        while ($waited -lt 15) {
            Start-Sleep -Seconds 1
            $waited++
            $still = Get-CimInstance Win32_Process -Filter "Name='python.exe'" |
                Where-Object { $_.CommandLine -like '*wled_controller*' -and $_.CommandLine -notlike '*demo*' -and $_.CommandLine -notlike '*vscode*' -and $_.CommandLine -notlike '*isort*' }
            if (-not $still) {
                Write-Host "  Server exited cleanly after ${waited}s"
                break
            }
        }
        # Step 3: Force-kill stragglers
        $still = Get-CimInstance Win32_Process -Filter "Name='python.exe'" |
            Where-Object { $_.CommandLine -like '*wled_controller*' -and $_.CommandLine -notlike '*demo*' -and $_.CommandLine -notlike '*vscode*' -and $_.CommandLine -notlike '*isort*' }
        if ($still) {
            Write-Host "  Force-killing remaining processes..."
            foreach ($p in $still) {
                Stop-Process -Id $p.ProcessId -Force -ErrorAction SilentlyContinue
            }
            Start-Sleep -Seconds 1
        }
    } else {
        # No API key or API call failed — force-kill directly
        foreach ($p in $procs) {
            Write-Host "Stopping server (PID $($p.ProcessId))..."
            Stop-Process -Id $p.ProcessId -Force -ErrorAction SilentlyContinue
        }
        Start-Sleep -Seconds 2
    }
}

# Merge registry PATH with current PATH so newly-installed tools (e.g. scrcpy) are visible
$regUser = [Environment]::GetEnvironmentVariable('PATH', 'User')
if ($regUser) {
    $currentDirs = $env:PATH -split ';' | ForEach-Object { $_.TrimEnd('\') }
    foreach ($dir in ($regUser -split ';')) {
        if ($dir -and ($currentDirs -notcontains $dir.TrimEnd('\'))) {
            $env:PATH = "$env:PATH;$dir"
        }
    }
}

# Start server detached (set WLED_RESTART=1 to skip browser open)
Write-Host "Starting server..."
$env:WLED_RESTART = "1"
$pythonExe = (Get-Command python -ErrorAction SilentlyContinue).Source
if (-not $pythonExe) {
    # Fallback to known install location
    $pythonExe = "$env:LOCALAPPDATA\Programs\Python\Python313\python.exe"
}
Start-Process -FilePath $pythonExe -ArgumentList '-m', 'wled_controller' `
    -WorkingDirectory $serverRoot `
    -WindowStyle Hidden

Start-Sleep -Seconds 3

# Verify it's running
$check = Get-CimInstance Win32_Process -Filter "Name='python.exe'" |
    Where-Object { $_.CommandLine -like '*wled_controller*' -and $_.CommandLine -notlike '*demo*' -and $_.CommandLine -notlike '*vscode*' -and $_.CommandLine -notlike '*isort*' }
if ($check) {
    Write-Host "Server started (PID $($check[0].ProcessId))"
} else {
    Write-Host "WARNING: Server does not appear to be running!"
}
