# Nexus Shell POC â€” build portable laptop test package + update channel artifacts
# No secrets. No registry changes. No admin required for build.
param(
  [string]$Version = "0.1.0-poc1",
  [int]$Build = 1,
  [string]$OutputRoot = "",
  [string]$DownloadBaseUrl = "https://nexus.ninjakernen.info/downloads"
)

$ErrorActionPreference = "Stop"
$repoRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
$distRoot = if ($OutputRoot) { $OutputRoot } else { Join-Path $repoRoot "dist\nexus-laptop-poc" }
$staging = Join-Path $distRoot "staging"
$uploadRoot = Join-Path $distRoot "upload"
$releaseDir = Join-Path $uploadRoot "downloads\releases\$Version"
$packageName = "nexus-shell-poc"
$zipName = "$packageName.zip"

Write-Host "=== Nexus Laptop POC Package Build ===" -ForegroundColor Cyan
Write-Host "Version: $Version (build $Build)"
Write-Host "Repo:    $repoRoot"

if (Test-Path $staging) { Remove-Item -LiteralPath $staging -Recurse -Force }
New-Item -ItemType Directory -Path $staging -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $staging "shell") -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $staging "identity") -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $staging "logs") -Force | Out-Null
New-Item -ItemType Directory -Path (Join-Path $staging "data") -Force | Out-Null

Write-Host "Building Nexus Identity (Release, win-x64, framework-dependent)..." -ForegroundColor Cyan
dotnet publish "$repoRoot\source\nexus-identity\NexusIdentity.Api\NexusIdentity.Api.csproj" `
  -c Release -r win-x64 --self-contained false `
  -p:PublishSingleFile=false -o "$staging\identity"
if ($LASTEXITCODE -ne 0) { throw "Identity publish failed." }

Write-Host "Building Nexus Shell (Release, win-x64, framework-dependent)..." -ForegroundColor Cyan
dotnet publish "$repoRoot\source\nexus-shell\NexusShell\NexusShell.csproj" `
  -c Release -r win-x64 --self-contained false `
  -p:PublishSingleFile=false -o "$staging\shell"
if ($LASTEXITCODE -ne 0) { throw "Shell publish failed." }

$shellSettings = Join-Path $staging "shell\appsettings.json"
$settings = Get-Content $shellSettings -Raw | ConvertFrom-Json
$settings.Identity.Authority = "http://localhost:5050"
$settings | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $shellSettings -Encoding UTF8

$identitySettings = Join-Path $staging "identity\appsettings.json"
$identityCfg = Get-Content $identitySettings -Raw | ConvertFrom-Json
if (-not $identityCfg.PSObject.Properties.Match("Nexus").Count) {
  $identityCfg | Add-Member -NotePropertyName Nexus -NotePropertyValue ([pscustomobject]@{ SeedPocUsers = $true })
} elseif (-not $identityCfg.Nexus.PSObject.Properties.Match("SeedPocUsers").Count) {
  $identityCfg.Nexus | Add-Member -NotePropertyName SeedPocUsers -NotePropertyValue $true
} else {
  $identityCfg.Nexus.SeedPocUsers = $true
}
$identityCfg.Jwt.Issuer = "http://localhost:5050"
$dataDb = "..\data\identity\nexus-identity.db"
$identityCfg.ConnectionStrings.Identity = "Data Source=$dataDb"
$identityCfg | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath $identitySettings -Encoding UTF8

$templateDir = $PSScriptRoot
$scriptFiles = @(
  "README-FIRST.txt", "RECOVERY-INSTRUCTIONS.txt",
  "START-NEXUS-SAFE-MODE.ps1", "STOP-NEXUS.ps1",
  "UNINSTALL-NEXUS-POC.ps1", "VERIFY-NEXUS-POC.ps1",
  "apply-pending-update.ps1", "Start-Ninja-Nexus.bat"
)
foreach ($f in $scriptFiles) {
  Copy-Item -LiteralPath (Join-Path $templateDir $f) -Destination (Join-Path $staging $f) -Force
}

Set-Content -LiteralPath (Join-Path $staging "VERSION.txt") -Value $Version -Encoding UTF8

# ZIP staging
New-Item -ItemType Directory -Path $distRoot -Force | Out-Null
$zipPath = Join-Path $distRoot $zipName
if (Test-Path $zipPath) { Remove-Item -LiteralPath $zipPath -Force }
$items = Get-ChildItem -LiteralPath $staging -Force
Compress-Archive -Path ($items | ForEach-Object { $_.FullName }) -DestinationPath $zipPath -CompressionLevel Optimal

$hash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash.ToLowerInvariant()
$sizeBytes = (Get-Item -LiteralPath $zipPath).Length
$publishedAt = (Get-Date).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")

$notes = @(
  "Add workspace diagnostics, performance logging and window containment for Ninja Browser and Ninja Files."
)

$packageUrl = "$DownloadBaseUrl/releases/$Version/$zipName"

$manifest = [ordered]@{
  product                 = "Ninja Nexus"
  channel                 = "poc"
  version                 = $Version
  build                   = $Build
  publishedAt             = $publishedAt
  minimumSupportedBuild   = 1
  minimumSupportedVersion = $Version
  artifact                = [ordered]@{
    url       = $packageUrl
    sha256    = $hash
    sizeBytes = $sizeBytes
  }
  packageUrl              = $packageUrl
  sha256Url               = "$DownloadBaseUrl/releases/$Version/sha256.txt"
  sha256                  = $hash
  sizeBytes               = $sizeBytes
  notes                   = $notes
  releaseNotes            = $notes
  requiresRuntime         = @(".NET 8 Runtime", ".NET Desktop Runtime")
  requiresSafePoc         = $true
  mandatory               = $false
  rollbackVersion         = $null
  signature               = $null
}

function Write-Utf8NoBom([string]$Path, [string]$Content) {
  [System.IO.File]::WriteAllText($Path, $Content, (New-Object System.Text.UTF8Encoding $false))
}

# Upload folder mirror (for Coolify volume / manual upload)
New-Item -ItemType Directory -Path (Join-Path $uploadRoot "downloads") -Force | Out-Null
if (Test-Path $releaseDir) { Remove-Item -LiteralPath $releaseDir -Recurse -Force }
New-Item -ItemType Directory -Path $releaseDir -Force | Out-Null

Copy-Item -LiteralPath $zipPath -Destination (Join-Path $releaseDir $zipName) -Force
Copy-Item -LiteralPath $zipPath -Destination (Join-Path $uploadRoot "downloads\$zipName") -Force

$manifestJson = ($manifest | ConvertTo-Json -Depth 6 -Compress)
Write-Utf8NoBom (Join-Path $releaseDir "manifest.json") $manifestJson
Write-Utf8NoBom (Join-Path $uploadRoot "downloads\latest.json") ($manifest | ConvertTo-Json -Depth 6 -Compress)

$shaLine = "$hash  $zipName"
Write-Utf8NoBom (Join-Path $releaseDir "sha256.txt") "$shaLine`n"
Write-Utf8NoBom (Join-Path $uploadRoot "downloads\sha256.txt") "$shaLine`n"

# Dist copies for local reference
Write-Utf8NoBom (Join-Path $distRoot "latest.json") ($manifest | ConvertTo-Json -Depth 6 -Compress)
Write-Utf8NoBom (Join-Path $distRoot "sha256.txt") "$shaLine`n"
New-Item -ItemType Directory -Path (Join-Path $distRoot "releases\$Version") -Force | Out-Null
Copy-Item -LiteralPath (Join-Path $releaseDir "manifest.json") -Destination (Join-Path $distRoot "releases\$Version\manifest.json") -Force
Copy-Item -LiteralPath (Join-Path $releaseDir "sha256.txt") -Destination (Join-Path $distRoot "releases\$Version\sha256.txt") -Force
Copy-Item -LiteralPath $zipPath -Destination (Join-Path $distRoot "releases\$Version\$zipName") -Force

Get-ChildItem -LiteralPath $staging -Recurse -File |
  ForEach-Object { $_.FullName.Substring($staging.Length + 1) } |
  Sort-Object |
  Set-Content -LiteralPath (Join-Path $distRoot "file-list.txt") -Encoding UTF8

Write-Host ""
Write-Host "Package:      $zipPath" -ForegroundColor Green
Write-Host "Upload root:  $uploadRoot" -ForegroundColor Green
Write-Host "Size:         $sizeBytes bytes" -ForegroundColor Green
Write-Host "SHA256:       $hash" -ForegroundColor Green

return [pscustomobject]@{
  ZipPath      = $zipPath
  UploadRoot   = $uploadRoot
  ManifestPath = Join-Path $uploadRoot "downloads\latest.json"
  ReleaseManifestPath = Join-Path $releaseDir "manifest.json"
  Sha256       = $hash
  SizeBytes    = $sizeBytes
  Version      = $Version
  Build        = $Build
}
