param(
  [string]$SetupExe,
  [string]$BaseOutputDir,
  [int]$InstallTimeoutSeconds = 480
)

$ErrorActionPreference = 'Stop'

$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path
$installerSmokeScript = Join-Path $repoRoot 'build\scripts\installer-smoke.ps1'
$installerDir = Join-Path $repoRoot 'dist\installer'

if (-not $SetupExe) {
  $latestSetup = Get-ChildItem -Path $installerDir -Filter '*-Setup-*.exe' |
    Sort-Object LastWriteTime -Descending |
    Select-Object -First 1

  if (-not $latestSetup) {
    throw "No installer exe found under $installerDir"
  }

  $SetupExe = $latestSetup.FullName
}

$SetupExe = (Resolve-Path $SetupExe).Path
$setupFileName = [System.IO.Path]::GetFileName($SetupExe)
$setupMarker = '-Setup-'
$setupMarkerIndex = $setupFileName.LastIndexOf($setupMarker, [System.StringComparison]::Ordinal)
if ($setupMarkerIndex -le 0) {
  throw "Unable to derive product name from setup executable: $setupFileName"
}

$productName = $setupFileName.Substring(0, $setupMarkerIndex)

if (-not $BaseOutputDir) {
  $BaseOutputDir = Join-Path $repoRoot '.tmp\installer-target-residue-smoke'
}
$BaseOutputDir = [System.IO.Path]::GetFullPath($BaseOutputDir)

if (Test-Path $BaseOutputDir) {
  Remove-Item -Path $BaseOutputDir -Recurse -Force -ErrorAction SilentlyContinue
}
New-Item -ItemType Directory -Force -Path $BaseOutputDir | Out-Null

$installDir = Join-Path $BaseOutputDir (Join-Path 'target' $productName)
$resultPath = Join-Path $BaseOutputDir 'installer-target-residue-result.json'
$staleUninstallerPath = Join-Path $installDir "Uninstall $productName.exe"

New-Item -ItemType Directory -Force -Path $installDir | Out-Null
[System.IO.File]::WriteAllText($staleUninstallerPath, 'stale residue', (New-Object System.Text.UTF8Encoding $false))

Write-Host "Running installer smoke against target with a preseeded stale uninstaller: $staleUninstallerPath"
powershell -ExecutionPolicy Bypass -File $installerSmokeScript `
  -SetupExe $SetupExe `
  -InstallDir $installDir `
  -SmokeOutput $resultPath `
  -InstallTimeoutSeconds $InstallTimeoutSeconds `
  -SkipInstalledAppSmoke
if ($LASTEXITCODE -ne 0) {
  exit $LASTEXITCODE
}

$result = Get-Content -LiteralPath $resultPath | ConvertFrom-Json
if (-not $result.ok) {
  throw 'Installer target residue smoke did not report ok=true.'
}
if (-not $result.uninstallerExists) {
  throw 'Installer target residue smoke did not materialize the uninstaller after residue cleanup.'
}

$summary = [ordered]@{
  ok = $true
  setupExe = $SetupExe
  installDir = $installDir
  staleUninstallerPath = $staleUninstallerPath
  resultPath = $resultPath
  installerExitCode = $result.installerExitCode
  fileCount = $result.fileCount
  uninstallerExists = $result.uninstallerExists
}

[System.IO.File]::WriteAllText((Join-Path $BaseOutputDir 'installer-target-residue-summary.json'), ($summary | ConvertTo-Json -Depth 12), (New-Object System.Text.UTF8Encoding $false))
Write-Output ($summary | ConvertTo-Json -Depth 12)
