[CmdletBinding()]
param(
    [string]$HostName = "panopainter-mac",
    [string]$RemoteDirectory = "~/Dev/panopainter",
    [string]$RepositoryUrl = "ssh://git@git.omar.synology.me:3022/omar/panopainter.git",
    [string]$Branch = "codex/modernization-cmake-foundation",
    [string[]]$Presets = @("macos", "ios-simulator", "ios-device"),
    [switch]$Quiet,
    [string]$LogDir = "out/logs/apple-remote-build",
    [int]$FailureTailLines = 0
)

$ErrorActionPreference = "Stop"

function Join-RemoteArgument {
    param([string[]]$Values)

    $expanded = @()
    foreach ($value in $Values) {
        foreach ($part in ($value -split ",")) {
            $trimmed = $part.Trim()
            if ($trimmed.Length -gt 0) {
                $expanded += $trimmed
            }
        }
    }
    return ($expanded -join " ")
}

function ConvertTo-ShellSingleQuoted {
    param([string]$Value)

    return "'" + ($Value -replace "'", "'\\''") + "'"
}

$presetArgument = Join-RemoteArgument -Values $Presets
$remoteDirectoryLiteral = ConvertTo-ShellSingleQuoted -Value $RemoteDirectory
$repositoryLiteral = ConvertTo-ShellSingleQuoted -Value $RepositoryUrl
$branchLiteral = ConvertTo-ShellSingleQuoted -Value $Branch
$presetLiteral = ConvertTo-ShellSingleQuoted -Value $presetArgument

$quietLiteral = if ($Quiet) { "1" } else { "0" }

$remoteScript = @"
set -eu
export PATH="/opt/homebrew/bin:/usr/local/bin:`$HOME/tools/bin:`$PATH"
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"

remote_dir=$remoteDirectoryLiteral
repository_url=$repositoryLiteral
branch_name=$branchLiteral
presets=$presetLiteral
quiet_mode=$quietLiteral

case "`$remote_dir" in
    "~/"*) remote_dir="`$HOME/`$(printf '%s' "`$remote_dir" | sed 's|^~/||')" ;;
esac

mkdir -p "`$(dirname "`$remote_dir")"
if [ ! -d "`$remote_dir/.git" ]; then
    git clone "`$repository_url" "`$remote_dir"
fi

cd "`$remote_dir"
git fetch origin
git checkout "`$branch_name"
git pull --ff-only origin "`$branch_name"

git submodule update --init --recursive \
    libs/tinyxml2 \
    libs/glm \
    libs/stb/stb \
    libs/yoga \
    libs/poly2tri \
    libs/base64 \
    libs/sqlite3 \
    libs/nanort \
    libs/hash-library \
    libs/fmt \
    libs/glad \
    libs/tinyfiledialogs

mkdir -p out/logs
log="out/logs/apple-platform-build-`$(date +%Y%m%d-%H%M%S).log"
set +e
sh ./scripts/automation/platform-build.sh "`$presets" > "`$log" 2>&1
exit_code=`$?
set -e

printf '{"command":"apple-remote-build","host":"%s","branch":"%s","presets":"%s","log":"%s","exitCode":%s}\n' \
    "`$(hostname)" "`$branch_name" "`$presets" "`$log" "`$exit_code"
if [ "`$quiet_mode" != "1" ]; then
    tail -n 80 "`$log"
fi
exit "`$exit_code"
"@

$remoteScript = $remoteScript -replace "`r`n", "`n"
$encodedRemoteScript = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($remoteScript))
if (-not $Quiet) {
    & ssh -o BatchMode=yes $HostName "printf '%s' '$encodedRemoteScript' | base64 -D | sh"
    exit $LASTEXITCODE
}

New-Item -ItemType Directory -Force -Path $LogDir | Out-Null
$runId = Get-Date -Format "yyyyMMdd-HHmmss"
$logPath = Join-Path -Path $LogDir -ChildPath "$runId-apple-remote-build.log"
$stderrPath = Join-Path -Path $LogDir -ChildPath "$runId-apple-remote-build.stderr.log"
$started = Get-Date
$exitCode = 0
try {
    $process = Start-Process `
        -FilePath "ssh" `
        -ArgumentList @("-o", "BatchMode=yes", $HostName, "printf '%s' '$encodedRemoteScript' | base64 -D | sh") `
        -NoNewWindow `
        -Wait `
        -PassThru `
        -RedirectStandardOutput $logPath `
        -RedirectStandardError $stderrPath
    $exitCode = $process.ExitCode
}
catch {
    $_ | Out-File -LiteralPath $LogPath -Append -Encoding utf8
    $exitCode = 1
}
finally {
    if (Test-Path -LiteralPath $stderrPath) {
        Get-Content -LiteralPath $stderrPath | Out-File -LiteralPath $logPath -Append -Encoding utf8
        Remove-Item -LiteralPath $stderrPath -Force
    }
}

$rawLines = if (Test-Path -LiteralPath $logPath) {
    @(Get-Content -LiteralPath $logPath)
} else {
    @()
}
$remoteSummary = $null
foreach ($line in $rawLines) {
    if ($line -match '"command":"apple-remote-build"') {
        try {
            $remoteSummary = $line | ConvertFrom-Json
        }
        catch {
        }
    }
}

$payload = [ordered]@{
    command = "apple-remote-build"
    exitCode = $exitCode
    elapsedMs = [int]((Get-Date) - $started).TotalMilliseconds
    host = $HostName
    branch = $Branch
    presets = $Presets
    log = $logPath
}
if ($null -ne $remoteSummary) {
    $payload.remoteHost = $remoteSummary.host
    $payload.remoteLog = $remoteSummary.log
}
if ($exitCode -ne 0 -and $FailureTailLines -gt 0 -and $rawLines.Count -gt 0) {
    $payload.failureTail = @($rawLines | Select-Object -Last $FailureTailLines | ForEach-Object { [string]$_ })
}

$payload | ConvertTo-Json -Compress -Depth 6
exit $exitCode
