param(
  [Parameter(Mandatory = $true)] [string] $Installer
)

$ErrorActionPreference = 'Stop'
$installerPath = (Resolve-Path -LiteralPath $Installer).Path
$testRoot = Join-Path ([IO.Path]::GetTempPath()) "SmartCut64-installer-test-$PID"
$installRoot = Join-Path $testRoot 'application'
$uninstaller = $null
$uninstalled = $false
New-Item -ItemType Directory -Force -Path $testRoot | Out-Null
try {
  $install = Start-Process -FilePath $installerPath -ArgumentList "/S /D=$installRoot" -Wait -PassThru
  if ($install.ExitCode -ne 0) { throw "Silent installer failed with $($install.ExitCode)" }
  $bin = Join-Path $installRoot 'bin'
  $cli = Join-Path $bin 'smartcut-cli.exe'
  $gui = Join-Path $bin 'smartcut-gui.exe'
  $uninstaller = Join-Path $installRoot 'Uninstall.exe'
  foreach ($file in @($cli, $gui, $uninstaller)) {
    if (-not (Test-Path -LiteralPath $file)) { throw "Installed image is missing: $file" }
  }

  $classesRoot = 'HKCU:\Software\Classes'
  $projectClass = Join-Path $classesRoot 'SmartCut64.Project'
  $joinerClass = Join-Path $classesRoot 'SmartCut64.Joiner'
  $applicationClass = Join-Path $classesRoot 'Applications\smartcut-gui.exe'
  $mediaClass = Join-Path $classesRoot 'SystemFileAssociations\.mkv\shell\SmartCut64'
  $expectedCommand = '"' + $gui + '" "%1"'
  $registryChecks = @(
    @{ Path = (Join-Path $classesRoot '.smartcut'); Value = 'SmartCut64.Project' },
    @{ Path = (Join-Path $classesRoot '.scjoin'); Value = 'SmartCut64.Joiner' },
    @{ Path = (Join-Path $projectClass 'shell\open\command'); Value = $expectedCommand },
    @{ Path = (Join-Path $joinerClass 'shell\open\command'); Value = $expectedCommand },
    @{ Path = (Join-Path $applicationClass 'shell\open\command'); Value = $expectedCommand },
    @{ Path = (Join-Path $mediaClass 'command'); Value = $expectedCommand }
  )
  foreach ($check in $registryChecks) {
    if (-not (Test-Path -LiteralPath $check.Path)) { throw "Installer did not create shell registration: $($check.Path)" }
    $actual = (Get-Item -LiteralPath $check.Path).GetValue('')
    if ($actual -ne $check.Value) { throw "Unexpected shell registration at $($check.Path): $actual" }
  }

  $previousPath = $env:PATH
  $previousQpa = $env:QT_QPA_PLATFORM
  $env:PATH = "$env:SystemRoot\System32;$env:SystemRoot"
  $env:QT_QPA_PLATFORM = 'offscreen'
  try {
    $cliRun = Start-Process -FilePath $cli -ArgumentList '--versions' -WorkingDirectory $bin -Wait -PassThru -NoNewWindow
    if ($cliRun.ExitCode -ne 0) { throw "Installed CLI failed with $($cliRun.ExitCode)" }
    $guiRun = Start-Process -FilePath $gui -ArgumentList '--version' -WorkingDirectory $bin -Wait -PassThru -NoNewWindow
    if ($guiRun.ExitCode -ne 0) { throw "Installed GUI failed with $($guiRun.ExitCode)" }
  } finally {
    $env:PATH = $previousPath
    $env:QT_QPA_PLATFORM = $previousQpa
  }

  $uninstall = Start-Process -FilePath $uninstaller -ArgumentList '/S' -Wait -PassThru
  if ($uninstall.ExitCode -ne 0) { throw "Silent uninstaller failed with $($uninstall.ExitCode)" }
  $uninstalled = $true
  Start-Sleep -Milliseconds 500
  if (Test-Path -LiteralPath (Join-Path $installRoot 'bin\smartcut-gui.exe')) { throw 'Uninstall left application binaries behind' }
  foreach ($path in @(
    (Join-Path $classesRoot '.smartcut'),
    (Join-Path $classesRoot '.scjoin'),
    $projectClass,
    $joinerClass,
    $applicationClass,
    $mediaClass
  )) {
    if (Test-Path -LiteralPath $path) { throw "Uninstall left shell registration behind: $path" }
  }
  Write-Host "Installer gate passed: clean install, shell registration, isolated launch, and uninstall"
} finally {
  if (-not $uninstalled -and $uninstaller -and (Test-Path -LiteralPath $uninstaller)) {
    Start-Process -FilePath $uninstaller -ArgumentList '/S' -Wait -ErrorAction SilentlyContinue | Out-Null
  }
  if (Test-Path -LiteralPath $testRoot) { Remove-Item -LiteralPath $testRoot -Recurse -Force }
}
