# StatusQuo_Updates/scripts/rollback.ps1
# Kanonisches Rollback-Skript (Referenz). rollback.bat enthaelt diese Logik
# EINGEBETTET und laeuft vollstaendig OFFLINE. Beachtet .backupignore.
# Erwartet im Scope: $root, $stopBat, $startBat

$ErrorActionPreference = 'Stop'
# Erwartet im Scope: $root, $stopBat, $startBat
$_stopName  = if ($null -ne $stopBat)  { $stopBat }  else { 'stop.bat' }
$_startName = if ($null -ne $startBat) { $startBat } else { 'dgl.bat' }

# Ausschlussliste (identisch zu update.ps1): .backup nie anfassen, plus große
# Content-Ordner aus .backupignore — diese bleiben beim Rollback unverändert.
$_excl = @('.backup')
$_ignoreFile = Join-Path $root '.backupignore'
if (Test-Path -LiteralPath $_ignoreFile) {
    $_extra = @(Get-Content -LiteralPath $_ignoreFile | ForEach-Object { $_.Trim() } |
                Where-Object { $_ -ne '' -and -not $_.StartsWith('#') })
    $_excl = $_excl + $_extra
}
$_excl = @($_excl)   # strikt als Array (verhindert Skalar-Entpackung)

$bk = Join-Path $root '.backup'
if (-not (Test-Path -LiteralPath $bk)) {
    Write-Host "Kein Backup-Verzeichnis gefunden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
    return
}
$snaps = Get-ChildItem -LiteralPath $bk -Filter 'snapshot-*.zip' -ErrorAction SilentlyContinue | Sort-Object Name -Descending
if (-not $snaps) {
    Write-Host "Keine Sicherungen vorhanden. Sicherungen entstehen automatisch beim ersten Update." -ForegroundColor Red
    return
}

Write-Host ""
Write-Host "Verfügbare Sicherungen (neueste zuerst):" -ForegroundColor Cyan
$i = 0
foreach ($s in $snaps) {
    $size = '{0:N1} MB' -f ($s.Length / 1MB)
    $tag  = if ($i -eq 0) { "  <- neueste" } else { "" }
    Write-Host ("  [{0}] {1}  ({2}){3}" -f $i, $s.Name, $size, $tag)
    $i++
}
Write-Host ""
$c = Read-Host "Nummer der Sicherung wählen (Enter = neueste [0])"
if ($c -eq '') { $c = '0' }
if ($c -notmatch '^\d+$' -or [int]$c -ge $snaps.Count) {
    Write-Host "Ungültige Auswahl. Abgebrochen." -ForegroundColor Yellow
    return
}
$chosen = $snaps[[int]$c]
$zip    = $chosen.FullName

# Integrität der Sicherung prüfen, BEVOR irgendetwas ersetzt wird
Add-Type -AssemblyName System.IO.Compression.FileSystem
try {
    $z = [System.IO.Compression.ZipFile]::OpenRead($zip)
    $null = $z.Entries.Count
    $z.Dispose()
} catch {
    Write-Host "FEHLER: Sicherung ist beschädigt — Rollback abgebrochen: $zip" -ForegroundColor Red
    return
}

Write-Host ""
$yn = Read-Host "Stand '$($chosen.Name)' wiederherstellen? Der aktuelle Stand wird ersetzt! [j/N]"
if ($yn -notin 'j','J','y','Y') { Write-Host "Abgebrochen."; return }

# Server stoppen
Write-Host "Stoppe Server ..."
if ($_stopName -ne '') {
    $sp = Join-Path $root $_stopName
    if (Test-Path -LiteralPath $sp) { & cmd /c "`"$sp`""; Start-Sleep -Seconds 2 }
    else { Write-Host "  (Stop-Skript '$_stopName' nicht gefunden — übersprungen)" -ForegroundColor DarkYellow }
} else { Write-Host "  (Kein Stop-Skript konfiguriert — übersprungen)" -ForegroundColor DarkYellow }

# Aktuellen Stand beiseite verschieben (Sicherheitsnetz, kein Datenverlust)
$aside = Join-Path $bk ("_vor-rollback-" + (Get-Date -Format 'yyyyMMdd-HHmmss'))
New-Item -ItemType Directory -Path $aside -Force | Out-Null
Get-ChildItem -LiteralPath $root -Force | Where-Object { $_excl -notcontains $_.Name } | ForEach-Object {
    Move-Item -LiteralPath $_.FullName -Destination (Join-Path $aside $_.Name) -Force
}

# Sicherung wiederherstellen
try {
    Expand-Archive -LiteralPath $zip -DestinationPath $root -Force
    Write-Host "Stand wiederhergestellt: $($chosen.Name)" -ForegroundColor Green
} catch {
    Write-Host "FEHLER beim Wiederherstellen — mache Änderung rückgängig ..." -ForegroundColor Red
    Get-ChildItem -LiteralPath $root -Force | Where-Object { $_excl -notcontains $_.Name } |
        Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
    Get-ChildItem -LiteralPath $aside -Force | ForEach-Object {
        Move-Item -LiteralPath $_.FullName -Destination (Join-Path $root $_.Name) -Force
    }
    Write-Host "Vorheriger Zustand wiederhergestellt — kein Datenverlust." -ForegroundColor Yellow
    return
}

# Beiseite-Ordner aufräumen: nur die letzten 2 behalten
Get-ChildItem -LiteralPath $bk -Directory -Filter '_vor-rollback-*' -ErrorAction SilentlyContinue |
    Sort-Object Name -Descending | Select-Object -Skip 2 |
    Remove-Item -Recurse -Force -ErrorAction SilentlyContinue

# Server starten
$stp = Join-Path $root $_startName
if (Test-Path -LiteralPath $stp) {
    Start-Process -FilePath 'cmd.exe' -ArgumentList "/c `"$stp`"" -WindowStyle Hidden
    Write-Host "Server gestartet." -ForegroundColor Green
} else {
    Write-Host "Start-Skript '$_startName' nicht gefunden — bitte Server manuell starten." -ForegroundColor Yellow
}

Write-Host ""
Write-Host "=== Rollback abgeschlossen ===" -ForegroundColor Green
Write-Host "    Wiederhergestellt: $($chosen.Name)" -ForegroundColor Cyan
