<#
.SYNOPSIS
    Robuster Screenshot vom Android-Emulator/Gerät.

.DESCRIPTION
    Umgeht PowerShells UTF-16-Encoding-Problem bei Binärausgaben.
    Nutzt adb pull statt exec-out-Pipe, validiert den PNG-Header,
    und liefert als Fallback eine Text-Beschreibung der UI via uiautomator.

.PARAMETER OutputPath
    Zielpfad für den Screenshot. Standard: tmp/screenshot-<timestamp>.png

.PARAMETER Target
    'emulator' (Standard) oder 'device'.

.PARAMETER UiDump
    Zusätzlich UI-Hierarchie als Text ausgeben (nützlich für automatische Verifikation).

.EXAMPLE
    & ".github/skills/android-build/screenshot.ps1"
    & ".github/skills/android-build/screenshot.ps1" -UiDump
    & ".github/skills/android-build/screenshot.ps1" -OutputPath "my-screenshot.png"
#>
param(
    [string]$OutputPath,
    [ValidateSet('emulator', 'device')]
    [string]$Target = 'emulator',
    [switch]$UiDump
)

$ErrorActionPreference = 'Stop'

# --- Konfiguration ---
$SDK_ROOT = "C:\Users\JensR\AppData\Local\Android\Sdk"
$ADB = "$SDK_ROOT\platform-tools\adb.exe"
$PROJECT_DIR = $PSScriptRoot | Split-Path | Split-Path | Split-Path
$ADB_TIMEOUT = 15  # Sekunden pro ADB-Kommando
$DEVICE_TMP = "/sdcard/screenshot-tmp.png"

# --- Hilfsfunktionen ---
function Write-Step { param([string]$msg) Write-Host ">> $msg" -ForegroundColor Cyan }
function Write-Ok   { param([string]$msg) Write-Host "OK $msg" -ForegroundColor Green }
function Write-Err  { param([string]$msg) Write-Host "ERR $msg" -ForegroundColor Red }

function Get-AdbFlag {
    if ($Target -eq 'device') { return '-d' }
    return '-e'
}

function Invoke-AdbWithTimeout {
    param(
        [string[]]$Arguments,
        [int]$TimeoutSec = $ADB_TIMEOUT
    )
    $psi = [System.Diagnostics.ProcessStartInfo]::new($ADB)
    $psi.Arguments = $Arguments -join ' '
    $psi.RedirectStandardOutput = $true
    $psi.RedirectStandardError = $true
    $psi.UseShellExecute = $false
    $psi.CreateNoWindow = $true

    $proc = [System.Diagnostics.Process]::Start($psi)
    $stdout = $proc.StandardOutput.ReadToEnd()
    $stderr = $proc.StandardError.ReadToEnd()
    $exited = $proc.WaitForExit($TimeoutSec * 1000)

    if (-not $exited) {
        $proc.Kill()
        throw "ADB-Timeout nach ${TimeoutSec}s: $($Arguments -join ' ')"
    }

    return @{
        ExitCode = $proc.ExitCode
        Stdout   = $stdout
        Stderr   = $stderr
    }
}

# --- Verbindung prüfen ---
$flag = Get-AdbFlag
Write-Step "Prüfe $Target-Verbindung..."
try {
    $check = Invoke-AdbWithTimeout @($flag, 'get-state') -TimeoutSec 5
    if ($check.Stdout.Trim() -ne 'device') {
        Write-Err "$Target nicht verbunden (Status: $($check.Stdout.Trim()))"
        exit 1
    }
}
catch {
    Write-Err "$Target nicht erreichbar: $_"
    exit 1
}
Write-Ok "$Target verbunden"

# --- Zielpfad bestimmen ---
$tmpDir = Join-Path $PROJECT_DIR "tmp"
if (-not (Test-Path $tmpDir)) { New-Item -ItemType Directory -Path $tmpDir -Force | Out-Null }

if (-not $OutputPath) {
    $timestamp = Get-Date -Format "yyyyMMdd-HHmmss"
    $OutputPath = Join-Path $tmpDir "screenshot-$timestamp.png"
}
elseif (-not [System.IO.Path]::IsPathRooted($OutputPath)) {
    $OutputPath = Join-Path $PROJECT_DIR $OutputPath
}

# --- Screenshot aufnehmen ---
Write-Step "Screenshot aufnehmen..."

# Schritt 1: Screenshot auf dem Gerät erstellen
try {
    $cap = Invoke-AdbWithTimeout @($flag, 'shell', 'screencap', '-p', $DEVICE_TMP) -TimeoutSec $ADB_TIMEOUT
    if ($cap.ExitCode -ne 0) {
        Write-Err "screencap fehlgeschlagen: $($cap.Stderr)"
        exit 1
    }
}
catch {
    Write-Err "screencap abgebrochen: $_"
    exit 1
}

# Schritt 2: Datei vom Gerät holen (adb pull = binärsicher)
try {
    $pull = Invoke-AdbWithTimeout @($flag, 'pull', $DEVICE_TMP, $OutputPath) -TimeoutSec $ADB_TIMEOUT
    if ($pull.ExitCode -ne 0) {
        Write-Err "adb pull fehlgeschlagen: $($pull.Stderr)"
        exit 1
    }
}
catch {
    Write-Err "adb pull abgebrochen: $_"
    exit 1
}

# Schritt 3: Temp-Datei auf dem Gerät löschen
try {
    Invoke-AdbWithTimeout @($flag, 'shell', 'rm', '-f', $DEVICE_TMP) -TimeoutSec 5 | Out-Null
}
catch {
    # Nicht kritisch
}

# --- PNG validieren ---
if (-not (Test-Path $OutputPath)) {
    Write-Err "Screenshot-Datei nicht erstellt: $OutputPath"
    exit 1
}

$fileInfo = Get-Item $OutputPath
if ($fileInfo.Length -eq 0) {
    Remove-Item $OutputPath -Force
    Write-Err "Screenshot-Datei ist leer (0 Bytes)"
    exit 1
}

$bytes = [System.IO.File]::ReadAllBytes($OutputPath)
$pngMagic = @(0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A)
$headerValid = $true
for ($i = 0; $i -lt 8; $i++) {
    if ($bytes[$i] -ne $pngMagic[$i]) { $headerValid = $false; break }
}

if (-not $headerValid) {
    $hexHeader = ($bytes[0..7] | ForEach-Object { "{0:X2}" -f $_ }) -join " "
    Write-Err "Ungültiger PNG-Header: $hexHeader (erwartet: 89 50 4E 47 0D 0A 1A 0A)"
    Write-Err "Mögliche Ursache: PowerShell UTF-16-Encoding oder Geräte-Fehler"
    Remove-Item $OutputPath -Force
    exit 1
}

$sizeKB = [math]::Round($fileInfo.Length / 1KB)
$relativePath = $OutputPath.Replace("$PROJECT_DIR\", "")
Write-Ok "Screenshot gespeichert: $relativePath (${sizeKB} KB, PNG validiert)"

# --- UI-Dump (optional) ---
if ($UiDump) {
    Write-Step "UI-Hierarchie auslesen..."
    try {
        Invoke-AdbWithTimeout @($flag, 'shell', 'uiautomator', 'dump', '/sdcard/ui-dump.xml') -TimeoutSec 10 | Out-Null
        $xmlResult = Invoke-AdbWithTimeout @($flag, 'shell', 'cat', '/sdcard/ui-dump.xml') -TimeoutSec 5
        Invoke-AdbWithTimeout @($flag, 'shell', 'rm', '-f', '/sdcard/ui-dump.xml') -TimeoutSec 5 | Out-Null

        # Sichtbare Texte extrahieren
        $texts = [regex]::Matches($xmlResult.Stdout, 'text="([^"]+)"') |
            ForEach-Object { $_.Groups[1].Value } |
            Where-Object { $_ -ne "" }

        if ($texts.Count -gt 0) {
            Write-Step "Sichtbare Texte auf dem Bildschirm:"
            $texts | ForEach-Object { Write-Host "  · $_" -ForegroundColor White }
        }
        else {
            Write-Host "  (keine Texte gefunden)" -ForegroundColor DarkGray
        }
    }
    catch {
        Write-Err "UI-Dump fehlgeschlagen: $_"
    }
}

exit 0
