param(
  [switch]$UseExistingPwa,
  [switch]$ReleaseCandidate
)

$ErrorActionPreference = "Stop"
$env:DOTNET_CLI_TELEMETRY_OPTOUT = "1"
$root = Split-Path -Parent $PSScriptRoot
$work = Join-Path $root "dist\windows-installer"
$publish = Join-Path $work "setup-app"
$layout = Join-Path $work "layout"
$backendRuntime = Join-Path $layout "app\backend"
$pwaRuntime = Join-Path $layout "app\pwa"
$hostRuntime = Join-Path $layout "host"
$legalRuntime = Join-Path $layout "Legal"
$outputDirectory = if ($ReleaseCandidate) { Join-Path $root "dist\release-candidate" } else { Join-Path $root "dist" }
$output = Join-Path $outputDirectory "CodeRemoteManagerSetup.exe"
$version = (Get-Content -LiteralPath (Join-Path $root "package.json") -Raw | ConvertFrom-Json).version

if ($env:CODE_REMOTE_MANAGER_SIGN_CERT_SHA1) {
  throw "Signing requires the verified release workflow. Run npm run release:verify first."
}

Remove-Item -LiteralPath $work -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -LiteralPath $output -Force -ErrorAction SilentlyContinue
New-Item -ItemType Directory -Force -Path $work, $publish, $layout, $pwaRuntime, $hostRuntime, $legalRuntime, $outputDirectory | Out-Null

if ($UseExistingPwa) {
  if (-not (Test-Path -LiteralPath (Join-Path $root "apps\pwa\dist\index.html"))) { throw "Existing PWA build is missing." }
} else {
  & npm.cmd --workspace apps/pwa exec vite build
  if ($LASTEXITCODE -ne 0) { throw "PWA build failed." }
}

& node (Join-Path $root "tools\release-candidate.mjs") verify-pwa-notices
if ($LASTEXITCODE -ne 0) { throw "PWA third-party notices are stale." }

& dotnet publish (Join-Path $root "windows-host\SetupApp\CodeRemoteManagerSetupApp.csproj") -c Release -r win-x64 --self-contained true -p:PublishSingleFile=true -p:DebugType=None -p:DebugSymbols=false -o $publish
if ($LASTEXITCODE -ne 0) { throw "Desktop setup app build failed." }

$node = (Get-Command node.exe).Source
& $node (Join-Path $root "tools\stage-windows-backend-runtime.mjs") $root $backendRuntime
if ($LASTEXITCODE -ne 0) { throw "Backend runtime staging failed." }

Copy-Item -LiteralPath $node -Destination (Join-Path $layout "node.exe")
Copy-Item -LiteralPath (Join-Path $publish "CodeRemoteManager.exe") -Destination (Join-Path $layout "CodeRemoteManager.exe")
Copy-Item -LiteralPath (Join-Path $root "windows-host\host.mjs") -Destination $hostRuntime
Copy-Item -LiteralPath (Join-Path $root "windows-host\host-lib.mjs") -Destination $hostRuntime
Copy-Item -LiteralPath (Join-Path $root "windows-host\start-host.vbs") -Destination $layout
Copy-Item -Path (Join-Path $root "apps\pwa\dist\*") -Destination $pwaRuntime -Recurse
Copy-Item -LiteralPath (Join-Path $root "distribution\PRIVACY.txt") -Destination $legalRuntime
Copy-Item -LiteralPath (Join-Path $root "distribution\TERMS.txt") -Destination $legalRuntime
Copy-Item -LiteralPath (Join-Path $root "distribution\THIRD_PARTY_NOTICES.txt") -Destination $legalRuntime
Copy-Item -LiteralPath (Join-Path $root "apps\pwa\public\legal\PWA-THIRD-PARTY-NOTICES.txt") -Destination $legalRuntime
Copy-Item -LiteralPath (Join-Path $root "distribution\QRCODER-LICENSE.txt") -Destination $legalRuntime
Copy-Item -LiteralPath (Join-Path $root "distribution\WINDOWS_INSTALL.txt") -Destination $legalRuntime

& $node (Join-Path $root "tools\release-candidate.mjs") verify-pwa-copy (Join-Path $root "apps\pwa\dist") $pwaRuntime
if ($LASTEXITCODE -ne 0) { throw "Packaged PWA verification failed." }

$npmNotices = Join-Path $legalRuntime "NPM-THIRD-PARTY-NOTICES.txt"
& node (Join-Path $root "tools\generate-third-party-notices.mjs") (Join-Path $backendRuntime "node_modules") $npmNotices
if ($LASTEXITCODE -ne 0) { throw "Third-party notice generation failed." }
$nodeVersion = (& node -p "process.versions.node").Trim()
$nodeLicense = Join-Path $legalRuntime "NODEJS-LICENSE.txt"
Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/nodejs/node/v$nodeVersion/LICENSE" -OutFile $nodeLicense
if (-not (Test-Path -LiteralPath $nodeLicense)) { throw "Node.js license download failed." }
$dotnetNotices = Join-Path (Split-Path (Get-Command dotnet.exe).Source -Parent) "ThirdPartyNotices.txt"
if (-not (Test-Path -LiteralPath $dotnetNotices)) { throw ".NET third-party notices are missing." }
Copy-Item -LiteralPath $dotnetNotices -Destination (Join-Path $legalRuntime "DOTNET-THIRD-PARTY-NOTICES.txt")

& $node (Join-Path $root "tools\smoke-windows-installed-layout.mjs") $layout
if ($LASTEXITCODE -ne 0) { throw "Installed-layout smoke failed." }

& $node (Join-Path $root "tools\smoke-windows-config-migration.mjs") $layout
if ($LASTEXITCODE -ne 0) { throw "Installed-layout configuration migration smoke failed." }

$compiler = Get-ChildItem -Path (Join-Path $env:LOCALAPPDATA "Programs\Inno Setup*"), "C:\Program Files (x86)\Inno Setup*" -Filter ISCC.exe -Recurse -ErrorAction SilentlyContinue | Select-Object -First 1 -ExpandProperty FullName
if (-not $compiler) { throw "Inno Setup 6 is required. Run: winget install --id JRSoftware.InnoSetup --exact" }
$iss = Join-Path $work "installer.iss"
$issText = @"
[Setup]
AppId={{A44FE547-94D5-4A60-80FB-FE7C3BC05461}
AppName=Code Remote Manager
AppVersion=$version
VersionInfoVersion=$version
AppPublisher=MakeCdev
AppPublisherURL=https://makecdev.com
AppSupportURL=https://coderemotemanager.makecdev.com/support
AppUpdatesURL=https://coderemotemanager.makecdev.com/download
AppCopyright=Copyright (C) 2026 MakeCdev. All rights reserved.
DefaultDirName={localappdata}\Programs\Code Remote Manager
DefaultGroupName=Code Remote Manager
OutputDir=$outputDirectory
OutputBaseFilename=CodeRemoteManagerSetup
Compression=lzma2/ultra64
SolidCompression=yes
PrivilegesRequired=lowest
ArchitecturesAllowed=x64compatible
ArchitecturesInstallIn64BitMode=x64compatible
UninstallDisplayName=Code Remote Manager
UsePreviousAppDir=yes
UsePreviousGroup=yes
LicenseFile=$layout\Legal\TERMS.txt
InfoBeforeFile=$layout\Legal\PRIVACY.txt
InfoAfterFile=$layout\Legal\WINDOWS_INSTALL.txt
CloseApplications=force
RestartApplications=no
WizardStyle=modern

[Files]
Source: "$layout\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsubdirs

[Icons]
Name: "{group}\Code Remote Manager PC Setup"; Filename: "{app}\CodeRemoteManager.exe"
Name: "{group}\Open Code Remote Manager"; Filename: "http://127.0.0.1:43111"
Name: "{group}\Privacy Notice"; Filename: "{app}\Legal\PRIVACY.txt"
Name: "{group}\Open Source Notices"; Filename: "{app}\Legal\THIRD_PARTY_NOTICES.txt"

[Registry]
Root: HKCU; Subkey: "Software\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "Code Remote Manager Host"; ValueData: "wscript.exe ""{app}\start-host.vbs"""; Flags: uninsdeletevalue

[Run]
Filename: "{app}\CodeRemoteManager.exe"; Description: "Open Code Remote Manager PC Setup"; Flags: nowait postinstall skipifsilent
"@
Set-Content -LiteralPath $iss -Value $issText -Encoding UTF8
& $compiler $iss
if ($LASTEXITCODE -ne 0) { throw "Installer compilation failed." }
if (-not (Test-Path -LiteralPath $output)) { throw "Installer EXE was not created." }

Write-Host "Created $output"
