param(
    [Parameter(Mandatory = $true)]
    [string]$CertificatePath,

    [Parameter(Mandatory = $true)]
    [string]$CertificatePassword,

    [Parameter(Mandatory = $false)]
    [string]$Version,

    [string]$OutputDirectory = 'artifacts/windows-installer'
)

$ErrorActionPreference = 'Stop'
$root = [System.IO.Path]::GetFullPath((Join-Path $PSScriptRoot '..\..'))
$project = Join-Path $root 'src\ServerMonitorManager.Desktop\ServerMonitorManager.Desktop.csproj'
$certificate = [System.IO.Path]::GetFullPath($CertificatePath)
$output = [System.IO.Path]::GetFullPath((Join-Path $root $OutputDirectory))
$appPackages = Join-Path $output 'AppPackages'

if (-not (Test-Path -LiteralPath $certificate -PathType Leaf)) {
    throw "Signing certificate not found: $certificate"
}

if (Test-Path -LiteralPath $output) {
    Remove-Item -LiteralPath $output -Recurse -Force
}
New-Item -ItemType Directory -Path $appPackages -Force | Out-Null

$securePassword = ConvertTo-SecureString -String $CertificatePassword -AsPlainText -Force
$signingCertificate = Import-PfxCertificate `
    -FilePath $certificate `
    -CertStoreLocation 'Cert:\CurrentUser\My' `
    -Password $securePassword `
    -Exportable
try {
    if ($signingCertificate.Subject -ne 'CN=AppPublisher') {
        throw "The certificate subject must match Package.appxmanifest Publisher=CN=AppPublisher; actual: $($signingCertificate.Subject)"
    }

    dotnet restore $project -p:Platform=x64 -p:PublishReadyToRun=false -p:RestoreLockedMode=true
    if ($LASTEXITCODE -ne 0) { throw 'dotnet restore failed' }

    if ($Version) {
        $dotnetArgs += "-p:Version=$Version"
        $dotnetArgs += "-p:AppxPackageVersion=$Version.0"
        dotnet publish $project `
            --configuration Release `
            --runtime win-x64 `
            --no-restore `
            -p:Platform=x64 `
            -p:PublishReadyToRun=false `
            -p:GenerateAppxPackageOnBuild=true `
            -p:AppxPackageSigningEnabled=true `
            -p:PackageCertificateThumbprint=$($signingCertificate.Thumbprint) `
            -p:AppxBundle=Never `
            -p:AppxSymbolPackageEnabled=false `
            -p:UapAppxPackageBuildMode=SideloadOnly `
            -p:AppxPackageDir="$appPackages\" `
            -p:Version=$Version
    } else {
        dotnet publish $project `
            --configuration Release `
            --runtime win-x64 `
            --no-restore `
            -p:Platform=x64 `
            -p:PublishReadyToRun=false `
            -p:GenerateAppxPackageOnBuild=true `
            -p:AppxPackageSigningEnabled=true `
            -p:PackageCertificateThumbprint=$($signingCertificate.Thumbprint) `
            -p:AppxBundle=Never `
            -p:AppxSymbolPackageEnabled=false `
            -p:UapAppxPackageBuildMode=SideloadOnly `
            -p:AppxPackageDir="$appPackages\"
    }
    if ($LASTEXITCODE -ne 0) { throw 'dotnet publish failed' }

    $package = Get-ChildItem -LiteralPath $appPackages -Recurse -File |
        Where-Object { $_.Extension -in @('.msix', '.appx', '.msixbundle', '.appxbundle') } |
        Sort-Object LastWriteTime -Descending |
        Select-Object -First 1
    if ($null -eq $package) {
        throw "No MSIX/AppX package was produced under $appPackages"
    }

    $finalPackage = Join-Path $output 'ServerMonitorManager-win-x64.msix'
    Copy-Item -LiteralPath $package.FullName -Destination $finalPackage -Force
    $signature = Get-AuthenticodeSignature -LiteralPath $finalPackage
    if ($null -eq $signature.SignerCertificate -or
        $signature.SignerCertificate.Thumbprint -ne $signingCertificate.Thumbprint) {
        throw 'The generated MSIX is not signed by the requested certificate.'
    }

    $hash = Get-FileHash -LiteralPath $finalPackage -Algorithm SHA256
    $checksumPath = Join-Path $output 'SHA256SUMS'
    "$($hash.Hash.ToLowerInvariant()) *$([System.IO.Path]::GetFileName($finalPackage))" |
        Set-Content -LiteralPath $checksumPath -Encoding ascii

    Write-Output "PACKAGE=$finalPackage"
    Write-Output "CHECKSUM=$checksumPath"
    Write-Output "SIGNER=$($signature.SignerCertificate.Subject)"
}
finally {
    Remove-Item -LiteralPath "Cert:\CurrentUser\My\$($signingCertificate.Thumbprint)" -Force -ErrorAction SilentlyContinue
}
