param(
    [string]$PackageRoot = 'C:\HyperTwist\packaged\higher-dimensional',
    [string]$MapUrl = '/Game/HyperTwistTraining/Maps/L_HyperTwist_Magic120CellTraining',
    [int]$SmokeSeconds = 10,
    [int]$ResX = 1600,
    [int]$ResY = 900,
    [string]$ReportPath = '',
    [switch]$KeepRunning
)

$ErrorActionPreference = 'Stop'

function Write-Utf8JsonFile {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Path,
        [Parameter(Mandatory = $true)]
        [object]$Value
    )

    $ParentPath = Split-Path -Parent $Path
    if (-not [string]::IsNullOrWhiteSpace($ParentPath))
    {
        New-Item -ItemType Directory -Force -Path $ParentPath | Out-Null
    }

    $Json = $Value | ConvertTo-Json -Depth 8
    $Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
    [System.IO.File]::WriteAllText($Path, $Json, $Utf8NoBom)
}

$CandidateExecutablePaths = @(
    (Join-Path $PackageRoot 'Windows\UnrealHyperTwist.exe'),
    (Join-Path $PackageRoot 'WindowsNoEditor\UnrealHyperTwist.exe'),
    (Join-Path $PackageRoot 'UnrealHyperTwist.exe')
)

$ExecutablePath = $CandidateExecutablePaths | Where-Object { Test-Path $_ } | Select-Object -First 1
if ($null -eq $ExecutablePath)
{
    throw "No packaged UnrealHyperTwist executable was found beneath '$PackageRoot'."
}

$ArgumentList = @(
    $MapUrl,
    "-ResX=$ResX",
    "-ResY=$ResY",
    '-windowed',
    '-log'
)

Write-Host "Launching packaged higher-dimensional validation lane from '$ExecutablePath'..."
$ResolvedPackageRoot = (Resolve-Path -LiteralPath $PackageRoot).Path
$GeneratedAtUtc = [DateTime]::UtcNow.ToString('o')
$Process = $null
$Report = [ordered]@{
    reportVersion = 'ht-higher-dimensional-package-smoke/v1'
    generatedAtUtc = $GeneratedAtUtc
    packageRoot = $ResolvedPackageRoot
    executablePath = $ExecutablePath
    mapUrl = $MapUrl
    smokeSeconds = $SmokeSeconds
    resolution = [ordered]@{
        width = $ResX
        height = $ResY
    }
    keepRunning = [bool]$KeepRunning
    result = 'failed'
    processId = $null
    processStopped = $false
    exitCode = $null
    error = $null
}

try
{
    $Process = Start-Process -FilePath $ExecutablePath -ArgumentList $ArgumentList -PassThru
    Start-Sleep -Seconds $SmokeSeconds

    $Process.Refresh()
    $Report.processId = $Process.Id
    if ($Process.HasExited)
    {
        $Report.exitCode = $Process.ExitCode
        throw "Packaged higher-dimensional executable exited early with code $($Process.ExitCode)."
    }

    $Report.result = 'passed'
}
catch
{
    $Report.error = $_.Exception.Message
    if ($null -ne $Process)
    {
        $Process.Refresh()
        if ($Process.HasExited)
        {
            $Report.exitCode = $Process.ExitCode
        }
        elseif (-not $KeepRunning)
        {
            Stop-Process -Id $Process.Id -Force
            $Report.processStopped = $true
        }
    }

    if (-not [string]::IsNullOrWhiteSpace($ReportPath))
    {
        Write-Utf8JsonFile -Path $ReportPath -Value $Report
    }

    throw
}

Write-Host "Packaged higher-dimensional smoke launch succeeded (PID $($Process.Id))."
if (-not $KeepRunning)
{
    Stop-Process -Id $Process.Id -Force
    $Report.processStopped = $true
    Write-Host 'Stopped packaged higher-dimensional smoke process after successful launch validation.'
}

if (-not [string]::IsNullOrWhiteSpace($ReportPath))
{
    Write-Utf8JsonFile -Path $ReportPath -Value $Report
}
