<#
  Builds a deployable release folder for the Purple Envelope Orders Site.

  "Build" for this Classic ASP app just means: assemble the exact file set that should ship
  to production, with the production web.config swapped in. There's no compile step.

  - Archives the given git ref via `git archive`, which respects .gitattributes
    export-ignore rules (drops docs/, tests/, .claude/, dev-only config, etc. - see
    .gitattributes for the full list).
  - Enforces $KeepTopLevel below as the authoritative allow-list: anything extracted from
    the archive that isn't on this list gets deleted. This is the real safety net - a file
    added to the repo root later and never added to .gitattributes would otherwise ship to
    production by default. Here, it has to be explicitly added to $KeepTopLevel to ship.
  - Overwrites public/web.config in the archive with public/web.config.production.template.
  - Leaves the assembled tree in -OutDir, ready to zip and ship.

  Usage:
    powershell -File scripts\build-release.ps1
    powershell -File scripts\build-release.ps1 -Ref master -OutDir dist\release
#>

param(
  [string]$Ref = 'HEAD',
  [string]$OutDir = ''
)

$ErrorActionPreference = 'Stop'

# Everything the live site needs to run: app code, framework internals, the IIS root, and
# the migration runner (+ its generator siblings, harmless to ship alongside it). Only
# db\migrations is kept under db - never db\webdata.accdb, even if something ever put a
# stray copy there.
$KeepTopLevel = @('app', 'core', 'public', 'public-admin', 'scripts', 'db')
$KeepUnderDb = @('migrations')

$repoRoot = Split-Path $PSScriptRoot -Parent
Push-Location $repoRoot
try {
  if([string]::IsNullOrWhiteSpace($OutDir)){
    $OutDir = Join-Path $repoRoot ('dist\release_' + (Get-Date -Format 'yyyyMMdd_HHmmss'))
  }
  if(Test-Path $OutDir){
    Remove-Item -Recurse -Force $OutDir
  }
  New-Item -ItemType Directory -Force -Path $OutDir | Out-Null

  $templatePath = Join-Path $repoRoot 'public\web.config.production.template'
  if(!(Test-Path $templatePath)){
    throw "public\web.config.production.template not found - can't build a production release without it."
  }

  Write-Host "Archiving $Ref (honoring .gitattributes export-ignore rules)..."
  $archivePath = Join-Path $OutDir '_archive.zip'
  git archive --format=zip --output $archivePath $Ref
  if($LASTEXITCODE -ne 0){ throw 'git archive failed' }

  Expand-Archive -Path $archivePath -DestinationPath $OutDir -Force
  Remove-Item $archivePath

  Write-Host "Pruning to the allow-list: $($KeepTopLevel -join ', '), db\$($KeepUnderDb -join ', db\')"
  Get-ChildItem -Path $OutDir -Force | ForEach-Object {
    if($_.Name -notin $KeepTopLevel){
      Write-Host "  removing (not on allow-list): $($_.Name)"
      Remove-Item -Recurse -Force $_.FullName
    }
  }
  $dbDir = Join-Path $OutDir 'db'
  if(Test-Path $dbDir){
    Get-ChildItem -Path $dbDir -Force | ForEach-Object {
      if($_.Name -notin $KeepUnderDb){
        Write-Host "  removing (not on allow-list): db\$($_.Name)"
        Remove-Item -Recurse -Force $_.FullName
      }
    }
  }

  if(!(Test-Path (Join-Path $OutDir 'public'))){
    throw "Release has no public\ folder after pruning - check `$KeepTopLevel in this script"
  }

  $liveConfig = Join-Path $OutDir 'public\web.config'
  Copy-Item $templatePath $liveConfig -Force
  Remove-Item (Join-Path $OutDir 'public\web.config.production.template') -ErrorAction SilentlyContinue

  $adminTemplatePath = Join-Path $repoRoot 'public-admin\web.config.production.template'
  if(Test-Path (Join-Path $OutDir 'public-admin')){
    if(Test-Path $adminTemplatePath){
      $adminLiveConfig = Join-Path $OutDir 'public-admin\web.config'
      Copy-Item $adminTemplatePath $adminLiveConfig -Force
      Remove-Item (Join-Path $OutDir 'public-admin\web.config.production.template') -ErrorAction SilentlyContinue
      Write-Host "  public-admin\web.config swapped in from web.config.production.template"
    }
  }

  Write-Host "Release built at $OutDir"
  Write-Host "  public\web.config swapped in from web.config.production.template"
} finally {
  Pop-Location
}
