<#
  Runs ON the IIS server (invoked over SSH by scripts\deploy-iis.ps1). Not meant to be run
  by hand except for troubleshooting a stuck deploy.

  - Stops the site/app pool
  - Wipes RemoteDir and re-extracts the release zip into it (safe: the DB and error log
    live outside RemoteDir, at DbPath/ErrorLogDir, so a full wipe never touches them)
  - Points IIS at RemoteDir\public
  - Ensures the app pool identity has modify rights on the persistent data folder
  - Runs pending migrations (32-bit cscript - ACE OLEDB is x86-only)
  - Restarts the site/app pool
#>

param(
  [Parameter(Mandatory = $true)][string]$ZipPath,
  [Parameter(Mandatory = $true)][string]$RemoteDir,
  [Parameter(Mandatory = $true)][string]$SiteName,
  [Parameter(Mandatory = $true)][string]$AppPool,
  [Parameter(Mandatory = $true)][string]$DbPath,
  [string]$AdminSiteName = '',
  [string]$AdminAppPool = '',
  [switch]$RunMigrations = $true
)

$ErrorActionPreference = 'Stop'
Import-Module WebAdministration

if(!(Get-Website -Name $SiteName -ErrorAction SilentlyContinue)){
  throw "IIS site '$SiteName' does not exist yet. Create the site and app pool once manually (or via a one-time setup script) before running this deploy."
}
if(!(Test-Path ('IIS:\AppPools\' + $AppPool))){
  throw "App pool '$AppPool' does not exist yet. Create it once manually before running this deploy."
}

Write-Host "Stopping IIS site $SiteName and app pool $AppPool"
try { Stop-Website -Name $SiteName } catch { }
try { Stop-WebAppPool -Name $AppPool } catch { }

if(Test-Path $RemoteDir){
  Write-Host "Wiping $RemoteDir"
  Remove-Item -Recurse -Force (Join-Path $RemoteDir '*') -ErrorAction SilentlyContinue
} else {
  New-Item -ItemType Directory -Force -Path $RemoteDir | Out-Null
}

Write-Host "Extracting $ZipPath -> $RemoteDir"
Expand-Archive -Path $ZipPath -DestinationPath $RemoteDir -Force
Remove-Item $ZipPath -ErrorAction SilentlyContinue

$publicDir = Join-Path $RemoteDir 'public'
if(!(Test-Path $publicDir)){
  throw "No public\ folder in the extracted release - deploy aborted, site left stopped for inspection."
}

# Persistent data folder (DB + error log) - lives outside RemoteDir so it survives the wipe
# above. Create it and grant the app pool identity modify rights.
$dataDir = Split-Path $DbPath -Parent
if(!(Test-Path $dataDir)){
  New-Item -ItemType Directory -Force -Path $dataDir | Out-Null
}
$logDir = Join-Path $dataDir 'logs'
if(!(Test-Path $logDir)){
  New-Item -ItemType Directory -Force -Path $logDir | Out-Null
}
icacls $dataDir /grant ("IIS AppPool\" + $AppPool + ":(OI)(CI)(M)") /T | Out-Null

Set-ItemProperty ('IIS:\Sites\' + $SiteName) -Name physicalPath -Value $publicDir
Set-ItemProperty ('IIS:\Sites\' + $SiteName) -Name applicationPool -Value $AppPool

# This server has the 64-bit Access Database Engine (ACE OLEDB) installed, unlike the local
# dev machine, which needs the 32-bit one - so the app pool stays 64-bit here.
Set-ItemProperty ('IIS:\AppPools\' + $AppPool) -Name enable32BitAppOnWin64 -Value $false

# --- Admin site ---
$adminPublicDir = Join-Path $RemoteDir 'public-admin'
if(![string]::IsNullOrWhiteSpace($AdminSiteName) -and (Test-Path $adminPublicDir)){
  if(!(Get-Website -Name $AdminSiteName -ErrorAction SilentlyContinue)){
    throw "IIS admin site '$AdminSiteName' does not exist yet. Create the site and app pool once manually before running this deploy."
  }
  Write-Host "Configuring admin site $AdminSiteName"
  Stop-Website -Name $AdminSiteName -ErrorAction SilentlyContinue
  if(![string]::IsNullOrWhiteSpace($AdminAppPool)){
    Stop-WebAppPool -Name $AdminAppPool -ErrorAction SilentlyContinue
    Set-ItemProperty ('IIS:\Sites\' + $AdminSiteName) -Name applicationPool -Value $AdminAppPool
    Set-ItemProperty ('IIS:\AppPools\' + $AdminAppPool) -Name enable32BitAppOnWin64 -Value $false
    icacls $dataDir /grant ("IIS AppPool\" + $AdminAppPool + ":(OI)(CI)(M)") /T | Out-Null
  }
  Set-ItemProperty ('IIS:\Sites\' + $AdminSiteName) -Name physicalPath -Value $adminPublicDir
}

if($RunMigrations){
  Write-Host 'Running pending migrations'
  Push-Location $RemoteDir
  try {
    & cscript.exe //nologo scripts\runMigrations.vbs up
    if($LASTEXITCODE -ne 0){ throw 'runMigrations.vbs up failed - see output above' }
  } finally {
    Pop-Location
  }
}

Write-Host "Starting IIS site $SiteName and app pool $AppPool"
if((Get-WebAppPoolState -Name $AppPool).Value -eq 'Started'){
  Restart-WebAppPool -Name $AppPool
} else {
  Start-WebAppPool -Name $AppPool
}
Start-Website $SiteName

if(![string]::IsNullOrWhiteSpace($AdminSiteName)){
  if(![string]::IsNullOrWhiteSpace($AdminAppPool)){
    if((Get-WebAppPoolState -Name $AdminAppPool).Value -eq 'Started'){
      Restart-WebAppPool -Name $AdminAppPool
    } else {
      Start-WebAppPool -Name $AdminAppPool
    }
  }
  Start-Website $AdminSiteName
}

Write-Host 'Remote apply complete.'
