# Startet ein Programm in der angemeldeten Windows-Sitzung - ueber die
# Desktop-Bridge statt ueber eine eigene geplante Aufgabe.
#
# Warum: GUI-Automation (Fenster finden, Tasten senden, Bildschirmfotos)
# braucht eine echte Desktop-Sitzung. Eine SSH-Sitzung hat keine. Bisher
# loeste das jedes Tool mit einer eigenen geplanten Aufgabe - gemessen
# 2,2 Sekunden Leerlauf pro Aufruf (anlegen, starten, abfragen, abmelden).
# Die Bridge laeuft ohnehin dauerhaft in der Sitzung; der Umweg entfaellt.
#
# Beispiel:
#   .\tools\Bridge-Run.ps1 -Exe .venv\Scripts\python.exe `
#       -Arguments 'tools\Login-Tibia.py' -TimeoutSeconds 180
param(
    [Parameter(Mandatory)]
    [string]$Exe,
    [string]$Arguments = '',
    [string]$WorkingDirectory = (Join-Path $env:USERPROFILE 'TibiaPilotNG'),
    [int]$TimeoutSeconds = 300,
    # Fuer Dauerlaeufer (OBS, Client): starten und sofort zurueckkehren,
    # statt auf ein Programmende zu warten, das nicht kommt.
    [switch]$Detached,
    [switch]$Quiet
)

$ErrorActionPreference = 'Stop'

$root = Join-Path $env:ProgramData 'TibiaPilotNG\DesktopBridge'
$inbox = Join-Path $root 'inbox'
$outbox = Join-Path $root 'outbox'
if (!(Test-Path $inbox)) {
    throw 'Die Desktop-Bridge ist nicht installiert (tools\Install-DesktopBridge.ps1 -Install).'
}

if (![IO.Path]::IsPathRooted($Exe)) {
    $Exe = Join-Path $WorkingDirectory $Exe
}

$id = [guid]::NewGuid().ToString()
$request = Join-Path $inbox "$id.json"
$temporary = Join-Path $inbox "$id.tmp"
$response = Join-Path $outbox "$id.json"

[ordered]@{
    action = 'run'
    exe = $Exe
    arguments = $Arguments
    workingDirectory = $WorkingDirectory
    timeoutSeconds = $TimeoutSeconds
    detached = [bool]$Detached
} | ConvertTo-Json -Compress | Set-Content $temporary -Encoding ascii
Move-Item $temporary $request -Force

try {
    # Die Bridge loescht die Anfrage, sobald sie sie gelesen hat. Liegt sie
    # nach ein paar Sekunden noch da, laeuft die Bridge nicht - dann sofort
    # abbrechen statt bis zum Zeitlimit zu warten.
    $pickUpDeadline = (Get-Date).AddSeconds(5)
    $deadline = (Get-Date).AddSeconds($TimeoutSeconds + 15)
    while (!(Test-Path $response)) {
        if ((Get-Date) -gt $deadline) {
            throw 'Die Desktop-Bridge hat nicht geantwortet.'
        }
        if ((Get-Date) -gt $pickUpDeadline -and (Test-Path $request)) {
            throw 'Die Desktop-Bridge laeuft nicht (Anfrage wurde nicht abgeholt).'
        }
        Start-Sleep -Milliseconds 5
    }
    $result = Get-Content $response -Raw | ConvertFrom-Json
    if (!$result.ok) { throw $result.error }
    if (!$Quiet) {
        if ($result.data.stdout) { Write-Output $result.data.stdout.TrimEnd() }
        if ($result.data.stderr) { Write-Output $result.data.stderr.TrimEnd() }
    }
    exit ([int]$result.data.exitCode)
}
finally {
    Remove-Item $request, $temporary, $response -Force -ErrorAction SilentlyContinue
}
