# Vendoo 1.41.2 – kontrollierter GitHub-Erstimport
$ErrorActionPreference = 'Stop'
$Root = Split-Path -Parent (Split-Path -Parent $MyInvocation.MyCommand.Path)
$RepoUrl = 'https://github.com/Masterluke77/vendoo.git'
$PullRequestUrl = 'https://github.com/Masterluke77/vendoo/pull/18'
$Branch = 'release/1.41.2-git-ignore-boundary-hotfix'
$WorkRoot = Join-Path $env:TEMP ('vendoo-github-deploy-' + [Guid]::NewGuid().ToString('N'))
$CloneDir = Join-Path $WorkRoot 'repo'

function Info($Text) { Write-Host "[INFO] $Text" -ForegroundColor Cyan }
function Ok($Text) { Write-Host "[OK]   $Text" -ForegroundColor Green }
function Warn($Text) { Write-Host "[WARN] $Text" -ForegroundColor Yellow }
function Fail($Text) { Write-Host "[FEHLER] $Text" -ForegroundColor Red }

function Test-Command([string]$Name) {
    return [bool](Get-Command $Name -ErrorAction SilentlyContinue)
}

function Ensure-Git {
    if (Test-Command 'git.exe') { return }
    Warn 'Git für Windows wurde nicht gefunden.'
    if (Test-Command 'winget.exe') {
        $answer = Read-Host 'Git jetzt automatisch über winget installieren? (ja/nein)'
        if ($answer -eq 'ja') {
            & winget.exe install --id Git.Git --exact --source winget --accept-package-agreements --accept-source-agreements
            if ($LASTEXITCODE -ne 0) { throw 'Git-Installation über winget ist fehlgeschlagen.' }
            $env:Path = [Environment]::GetEnvironmentVariable('Path','Machine') + ';' + [Environment]::GetEnvironmentVariable('Path','User')
        }
    }
    if (-not (Test-Command 'git.exe')) { throw 'Git für Windows wird benötigt. Starte den Assistenten nach der Git-Installation erneut.' }
}

function Invoke-Git([string[]]$Arguments, [string]$WorkingDirectory = $CloneDir) {
    Push-Location $WorkingDirectory
    try {
        & git.exe @Arguments
        if ($LASTEXITCODE -ne 0) { throw "git $($Arguments -join ' ') fehlgeschlagen (Exit-Code $LASTEXITCODE)." }
    } finally { Pop-Location }
}

function Copy-ProjectClean {
    if (-not (Test-Command 'node.exe')) {
        throw 'Node.js ist für den sicheren GitHub-Import erforderlich. Bitte zuerst über setup.bat installieren oder aktualisieren.'
    }
    Info 'Bereite den bereinigten Git-Arbeitsordner mit dem plattformübergreifenden Staging-Builder vor ...'
    $builder = Join-Path $Root 'tools\prepare-git-staging.mjs'
    $result = Invoke-NodeProcess -ScriptPath $builder -Arguments @($Root, $CloneDir) -WorkingDirectory $Root -Prefix 'Staging'
    if ($result.ExitCode -ne 0) {
        $result.Lines | ForEach-Object { Write-Host $_ -ForegroundColor Red }
        throw 'Der sichere Git-Staging-Aufbau ist fehlgeschlagen.'
    }
    $result.Lines | ForEach-Object { Write-Host $_ }
}

function Invoke-NodeProcess {
    param(
        [Parameter(Mandatory=$true)][string]$ScriptPath,
        [string[]]$Arguments = @(),
        [string]$WorkingDirectory = $CloneDir,
        [string]$Prefix = 'Node'
    )
    $id = [Guid]::NewGuid().ToString('N')
    $stdoutPath = Join-Path $WorkRoot ("$Prefix-$id-stdout.txt")
    $stderrPath = Join-Path $WorkRoot ("$Prefix-$id-stderr.txt")
    $nodePath = (Get-Command node.exe -ErrorAction Stop).Source
    $allArguments = @($ScriptPath) + $Arguments
    $argumentLine = ($allArguments | ForEach-Object { '"' + ([string]$_).Replace('"','\"') + '"' }) -join ' '
    $process = Start-Process -FilePath $nodePath `
        -ArgumentList $argumentLine `
        -WorkingDirectory $WorkingDirectory `
        -NoNewWindow `
        -Wait `
        -PassThru `
        -RedirectStandardOutput $stdoutPath `
        -RedirectStandardError $stderrPath

    $lines = @()
    if (Test-Path -LiteralPath $stdoutPath) { $lines += @(Get-Content -LiteralPath $stdoutPath -Encoding UTF8 -ErrorAction SilentlyContinue) }
    if (Test-Path -LiteralPath $stderrPath) { $lines += @(Get-Content -LiteralPath $stderrPath -Encoding UTF8 -ErrorAction SilentlyContinue) }
    return [pscustomobject]@{ ExitCode = [int]$process.ExitCode; Lines = $lines }
}

function Run-SafetyGate {
    $ReportDir = Join-Path $Root 'logs'
    $ReportPath = Join-Path $ReportDir 'github-deploy-safety-report.txt'
    if (-not (Test-Command 'node.exe')) {
        throw 'Node.js ist für den sicheren GitHub-Import erforderlich. Bitte zuerst über setup.bat installieren oder aktualisieren.'
    }

    Info 'Führe das Vendoo Git-Sicherheitsgate über den vollständigen Staging-Arbeitsbaum aus ...'
    $result = Invoke-NodeProcess -ScriptPath 'tools/verify-git-safety.mjs' -WorkingDirectory $CloneDir -Prefix 'SafetyGate'
    foreach ($line in $result.Lines) {
        if ($line -match '^Git-Sicherheitsgate fehlgeschlagen|^- ') { Write-Host $line -ForegroundColor Red }
        elseif ($line -match '^\[WARN\]') { Write-Host $line -ForegroundColor Yellow }
        else { Write-Host $line }
    }

    if ($result.ExitCode -ne 0) {
        New-Item -ItemType Directory -Path $ReportDir -Force | Out-Null
        @(
            'Vendoo Git-Sicherheitsgate – vollständiger Fehlerbericht',
            ('Zeitpunkt: ' + (Get-Date -Format 'yyyy-MM-dd HH:mm:ss')),
            ('Projekt: ' + $Root),
            ('Staging: ' + $CloneDir),
            '',
            $result.Lines
        ) | Set-Content -LiteralPath $ReportPath -Encoding UTF8
        Fail "Das Gate hat $($result.Lines.Count) Diagnosezeilen erzeugt. Bericht: $ReportPath"
        try { Start-Process notepad.exe -ArgumentList ('"' + $ReportPath + '"') | Out-Null } catch {}
        throw 'Git-Sicherheitsgate ist fehlgeschlagen. Die konkreten Treffer wurden oben angezeigt und im Bericht gespeichert.'
    }

    Remove-Item -LiteralPath $ReportPath -Force -ErrorAction SilentlyContinue
    $forbidden = Get-ChildItem -LiteralPath $CloneDir -Recurse -Force -File -ErrorAction SilentlyContinue | Where-Object {
        ($_.Name -match '^\.env(?:\..+)?$' -and $_.Name -notin @('.env.example','.env.docker.example')) -or
        $_.Extension -in @('.db','.sqlite','.sqlite3','.log','.key','.pem','.pfx','.p12')
    }
    if ($forbidden) {
        throw ('Verbotene Dateien im Git-Staging: ' + (($forbidden | Select-Object -First 20 -ExpandProperty FullName) -join ', '))
    }
    Ok 'Git-Sicherheitsgate erfolgreich: keine lokalen Secrets oder Laufzeitdaten im Import.'
}

try {
    Write-Host ''
    Write-Host 'Vendoo 1.41.2 – GitHub Deploy Assistent' -ForegroundColor Green
    Write-Host 'Repository: Masterluke77/vendoo (privat)' -ForegroundColor DarkGray
    Write-Host ''

    Ensure-Git
    New-Item -ItemType Directory -Path $WorkRoot -Force | Out-Null

    Info 'Klone die vorhandene GitHub-Baseline ...'
    & git.exe clone $RepoUrl $CloneDir
    if ($LASTEXITCODE -ne 0) { throw 'Repository konnte nicht geklont werden. Die Git-Anmeldung öffnet sich normalerweise automatisch im Browser.' }

    Push-Location $CloneDir
    try {
        & git.exe ls-remote --exit-code --heads origin $Branch 1>$null 2>$null
        $branchExists = ($LASTEXITCODE -eq 0)
    } finally { Pop-Location }
    if ($branchExists) {
        Invoke-Git @('fetch','origin',$Branch)
        Invoke-Git @('switch','--track','-c',$Branch,("origin/" + $Branch))
    } else {
        Invoke-Git @('switch','-c',$Branch)
    }

    Copy-ProjectClean
    Run-SafetyGate

    Info 'Prüfe produktive Source-Dateien und Git-Ignore-Grenzen im Staging ...'
    $sourceGate = Invoke-NodeProcess -ScriptPath 'tools/verify-source-boundaries-1.41.2.mjs' -WorkingDirectory $CloneDir -Prefix 'SourceGate'
    $sourceGate.Lines | ForEach-Object { Write-Host $_ }
    if ($sourceGate.ExitCode -ne 0) { throw 'Produktive Source-Root-Prüfung ist fehlgeschlagen.' }
    $ignoreGate = Invoke-NodeProcess -ScriptPath 'tools/verify-git-ignore-boundaries-1.41.2.mjs' -WorkingDirectory $CloneDir -Prefix 'IgnoreGate'
    $ignoreGate.Lines | ForEach-Object { Write-Host $_ }
    if ($ignoreGate.ExitCode -ne 0) { throw 'Git-Ignore-Grenzprüfung ist fehlgeschlagen.' }

    Invoke-Git @('config','user.name','Markus Müller')
    Invoke-Git @('config','user.email','163446896+Masterluke77@users.noreply.github.com')
    Invoke-Git @('add','--all')

    $requiredTracked = @(
        'app/modules/listings/routes.mjs',
        'app/modules/inventory/index.mjs',
        'app/modules/inventory/repository.mjs',
        'app/modules/inventory/routes.mjs',
        'app/modules/sessions/index.mjs'
    )
    Push-Location $CloneDir
    try {
        $ignoredModules = @(& git.exe ls-files --others --ignored --exclude-standard -- app/modules)
        if ($ignoredModules.Count -gt 0) { throw ('Produktive Moduldateien werden von .gitignore ausgeschlossen: ' + ($ignoredModules -join ', ')) }
        foreach ($rel in $requiredTracked) {
            if (-not (Test-Path -LiteralPath (Join-Path $CloneDir $rel))) { throw "Pflichtdatei fehlt im Git-Staging: $rel" }
            & git.exe ls-files --error-unmatch -- $rel 1>$null 2>$null
            if ($LASTEXITCODE -ne 0) { throw "Pflichtdatei wurde von Git nicht getrackt: $rel" }
        }
    } finally { Pop-Location }
    Ok 'Produktive Moduldateien sind vorhanden und werden von Git getrackt.'

    Push-Location $CloneDir
    try {
        $status = & git.exe status --short
        if (-not $status) { Warn 'Es gibt keine Änderungen gegenüber GitHub.'; exit 0 }
        Write-Host ''
        Write-Host $status
        Write-Host ''
    } finally { Pop-Location }

    $confirm = Read-Host 'Geprüften Vendoo-Stand als Release-Branch zu GitHub übertragen? Zum Fortfahren PUSH eingeben'
    if ($confirm -cne 'PUSH') { Warn 'Deployment abgebrochen. Auf GitHub wurde nichts verändert.'; exit 0 }

    Invoke-Git @('commit','-m','fix: track native source modules with root-anchored runtime ignores')
    Invoke-Git @('push','--set-upstream','origin',$Branch)
    Ok "Branch $Branch wurde erfolgreich übertragen."

    Info 'Öffne jetzt Draft Pull Request #18 im Browser ...'
    Start-Process $PullRequestUrl
    Write-Host ''
    Write-Host 'Nächster Schritt im Browser: Pull Request #18 und CI prüfen. Erst nach grüner CI nach main mergen.' -ForegroundColor Yellow
} catch {
    Fail $_.Exception.Message
    exit 1
} finally {
    if (Test-Path -LiteralPath $WorkRoot) {
        Remove-Item -LiteralPath $WorkRoot -Recurse -Force -ErrorAction SilentlyContinue
    }
}
