#Requires -Version 5.1
<#
.SYNOPSIS
  Builds a Libation Windows setup.exe from a published bin directory using Inno Setup.

.DESCRIPTION
  Optionally runs dotnet publish (same projects as CI), removes standalone WindowsConfigApp
  artifacts, then compiles Scripts/Windows/Libation.iss.

.PARAMETER Version
  Libation version string (e.g. 13.4.1).

.PARAMETER Ui
  Avalonia (Chardonnay) or WinForms (Classic). Classic is x64 only.

.PARAMETER Architecture
  x64 or arm64 (Avalonia only).

.PARAMETER BinDir
  Folder containing published files. Defaults to repo-root bin.

.PARAMETER SkipPublish
  Skip dotnet publish; BinDir must already contain a complete publish output.

.EXAMPLE
  .\Build-WindowsInstaller.ps1 -Version 13.4.1 -Ui Avalonia -Architecture x64

.EXAMPLE
  .\Build-WindowsInstaller.ps1 -Version 13.4.1 -Ui WinForms
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [string] $Version,

    [ValidateSet('Avalonia', 'WinForms')]
    [string] $Ui = 'Avalonia',

    [ValidateSet('x64', 'arm64')]
    [string] $Architecture = 'x64',

    [string] $BinDir = '',

    [switch] $SkipPublish
)

$ErrorActionPreference = 'Stop'

if ($Ui -eq 'WinForms' -and $Architecture -ne 'x64') {
    throw 'Classic (WinForms) is only published for x64.'
}

$repoRoot = Resolve-Path (Join-Path $PSScriptRoot '..\..')
$sourceDir = Join-Path $repoRoot 'Source'
if (-not $BinDir) {
    $BinDir = Join-Path $repoRoot 'bin'
}
if (-not (Test-Path $BinDir)) {
    New-Item -ItemType Directory -Path $BinDir -Force | Out-Null
}
$BinDir = (Resolve-Path $BinDir).Path

$runtime = "win-$Architecture"
$releaseName = if ($Ui -eq 'WinForms') { 'classic' } else { 'chardonnay' }
$outputBase = if ($Ui -eq 'WinForms') {
    "Libation-Classic.$Version-windows-$releaseName-$Architecture-setup"
} else {
    "Libation.$Version-windows-$releaseName-$Architecture-setup"
}
$architecturesAllowed = if ($Architecture -eq 'arm64') { 'arm64' } else { 'x64compatible' }

function Find-ISCC {
    $candidates = @(
        "${env:ProgramFiles(x86)}\Inno Setup 6\ISCC.exe",
        "$env:ProgramFiles\Inno Setup 6\ISCC.exe",
        "${env:LocalAppData}\Programs\Inno Setup 6\ISCC.exe"
    )
    foreach ($path in $candidates) {
        if (Test-Path $path) { return $path }
    }
    return $null
}

if (-not $SkipPublish -and (Test-Path $BinDir)) {
    Write-Host "Clearing $BinDir before publish ..."
    Get-ChildItem -LiteralPath $BinDir -Force | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
}

if (-not $SkipPublish) {
    Write-Host "Publishing Libation ($Ui, $runtime) to $BinDir ..."
    Push-Location $sourceDir
    try {
        $publishArgs = @(
            '--runtime', $runtime,
            '--configuration', 'Release',
            '--output', $BinDir,
            '-p:PublishProtocol=FileSystem',
            '-p:PublishReadyToRun=false',
            '-p:SelfContained=true'
        )
        dotnet publish "Libation$Ui/Libation$Ui.csproj" @publishArgs
        dotnet publish 'LoadByOS/WindowsConfigApp/WindowsConfigApp.csproj' @publishArgs
        dotnet publish 'LibationCli/LibationCli.csproj' @publishArgs
        dotnet publish "Hangover$Ui/Hangover$Ui.csproj" @publishArgs
    }
    finally {
        Pop-Location
    }
}

Write-Host 'Removing standalone WindowsConfigApp launcher artifacts ...'
$removeFiles = @(
    'WindowsConfigApp.exe',
    'WindowsConfigApp.runtimeconfig.json',
    'WindowsConfigApp.deps.json'
)
Push-Location $BinDir
try {
    foreach ($file in $removeFiles) {
        if (Test-Path $file) { Remove-Item $file -Force }
    }
    if (-not (Test-Path 'Libation.exe')) {
        throw "Libation.exe not found in $BinDir. Publish or point -BinDir at a complete output folder."
    }
    if (-not (Test-Path 'ZipExtractor.exe')) {
        throw "ZipExtractor.exe not found in $BinDir. It is required for in-app upgrades."
    }
}
finally {
    Pop-Location
}

$iscc = Find-ISCC
if (-not $iscc) {
    throw @"
Inno Setup 6 (ISCC.exe) was not found. Install from https://jrsoftware.org/isdl.php
and ensure ISCC.exe is under Program Files (x86)\Inno Setup 6\ or similar.
"@
}

$setupIcon = Join-Path $PSScriptRoot 'libation.ico'
if (-not (Test-Path $setupIcon)) {
    throw "Installer icon not found: $setupIcon"
}
$iss = Join-Path $PSScriptRoot 'Libation.iss'
$defines = @(
    "/DMyVersion=$Version",
    "/DMySetupIcon=$setupIcon",
    "/DMyReleaseName=$releaseName",
    "/DMyArchitecture=$Architecture",
    "/DOutputBaseFilename=$outputBase",
    "/DSourceDir=$BinDir",
    "/DOutputDir=$BinDir",
    "/DArchitecturesAllowed=$architecturesAllowed"
)

Write-Host "Compiling $outputBase.exe ..."
& $iscc $defines $iss
if ($LASTEXITCODE -ne 0) {
    throw "ISCC failed with exit code $LASTEXITCODE."
}

$setupPath = Join-Path $BinDir "$outputBase.exe"
Write-Host "Done: $setupPath"
