param(
  [Parameter(Mandatory = $true)]
  [string]$KubeContext,
  [Parameter(Mandatory = $true)]
  [string]$Namespace,
  [Parameter(Mandatory = $true)]
  [string]$Release,
  [Parameter(Mandatory = $true)]
  [string]$GatewayBaseUrl,
  [Parameter(Mandatory = $true)]
  [string]$DatabaseUrl,
  [Parameter(Mandatory = $true)]
  [string]$ImageTag,
  [Parameter(Mandatory = $true)]
  [string]$AmiHost,
  [Parameter(Mandatory = $true)]
  [string]$AmiUser,
  [Parameter(Mandatory = $true)]
  [string]$AmiSecret,
  [Parameter(Mandatory = $true)]
  [string]$SftpHost,
  [Parameter(Mandatory = $true)]
  [string]$SftpUser,
  [Parameter(Mandatory = $true)]
  [string]$SftpPassword,
  [Parameter(Mandatory = $true)]
  [string]$QueueId,
  [Parameter(Mandatory = $true)]
  [string]$AppTokenSecret,
  [string]$ScaleValuesPath = "deployment/helm/values.scale500.yaml",
  [string]$StrictValuesPath = "deployment/helm/values.track9-strict.yaml",
  [string]$EvidenceOutDir = "",
  [switch]$Execute,
  [switch]$ForceUpgrade,
  [switch]$SkipChecks
)

$ErrorActionPreference = "Stop"

$root = Split-Path -Parent $PSScriptRoot
Set-Location $root

function Run-Checked {
  param(
    [Parameter(Mandatory = $true)]
    [string]$Label,
    [Parameter(Mandatory = $true)]
    [string[]]$Args
  )
  Write-Host ""
  Write-Host "==> $Label"
  Write-Host "    $($Args -join ' ')"
  $command = $Args[0]
  $arguments = @()
  if ($Args.Length -gt 1) {
    $arguments = $Args[1..($Args.Length - 1)]
  }
  & $command @arguments
  if ($LASTEXITCODE -ne 0) {
    throw "$Label failed with exit code $LASTEXITCODE"
  }
}

function Ensure-File {
  param([string]$PathValue)
  if (-not (Test-Path $PathValue)) {
    throw "Required file not found: $PathValue"
  }
}

Ensure-File -PathValue $ScaleValuesPath
Ensure-File -PathValue $StrictValuesPath

$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$artifactsDir = Join-Path $root ".artifacts/track9_2/$timestamp"
New-Item -ItemType Directory -Path $artifactsDir -Force | Out-Null

$helmTemplateOut = Join-Path $artifactsDir "helm_template.yaml"
$cutoverValuesFile = Join-Path $artifactsDir "cutover.override.yaml"
$podsSnapshotOut = Join-Path $artifactsDir "pods_before.txt"
$historyBeforeOut = Join-Path $artifactsDir "helm_history_before.txt"
$historyAfterOut = Join-Path $artifactsDir "helm_history_after.txt"
$cutoverSummaryOut = Join-Path $artifactsDir "cutover-summary.txt"

function Escape-YamlSingleQuoted {
  param([string]$Value)
  return ($Value -replace "'", "''")
}

$queueMapJson = '{"voice_lab":"' + $QueueId + '"}'
$overrideYaml = @"
namespace: '$(Escape-YamlSingleQuoted $Namespace)'
image:
  tag: '$(Escape-YamlSingleQuoted $ImageTag)'
auth:
  appTokenSecret: '$(Escape-YamlSingleQuoted $AppTokenSecret)'
asteriskBridge:
  enabled: "1"
  amiHost: '$(Escape-YamlSingleQuoted $AmiHost)'
  amiUsername: '$(Escape-YamlSingleQuoted $AmiUser)'
  amiSecret: '$(Escape-YamlSingleQuoted $AmiSecret)'
  queueMapJson: '$(Escape-YamlSingleQuoted $queueMapJson)'
  sftpHost: '$(Escape-YamlSingleQuoted $SftpHost)'
  sftpUsername: '$(Escape-YamlSingleQuoted $SftpUser)'
  sftpPassword: '$(Escape-YamlSingleQuoted $SftpPassword)'
"@
$overrideYaml | Out-File -FilePath $cutoverValuesFile -Encoding utf8

Run-Checked -Label "Switch kube context" -Args @("kubectl", "config", "use-context", $KubeContext)

Run-Checked -Label "Helm lint" -Args @("helm", "lint", "deployment/helm")

Write-Host ""
Write-Host "==> Helm history (before)"
Write-Host "    helm -n $Namespace history $Release"
& helm -n $Namespace history $Release | Out-File -FilePath $historyBeforeOut -Encoding utf8
if ($LASTEXITCODE -ne 0) {
  "release not found (this can be valid for first install)" | Out-File -FilePath $historyBeforeOut -Encoding utf8
  Write-Warning "Release '$Release' not found in namespace '$Namespace'. Continuing with first-install flow."
}

Write-Host ""
Write-Host "==> Pods snapshot (before)"
Write-Host "    kubectl -n $Namespace get pods -o wide"
& kubectl -n $Namespace get pods -o wide | Out-File -FilePath $podsSnapshotOut -Encoding utf8
if ($LASTEXITCODE -ne 0) {
  "namespace missing or no pods yet (pre-install state)" | Out-File -FilePath $podsSnapshotOut -Encoding utf8
  Write-Warning "Could not fetch pods for namespace '$Namespace'. Continuing."
}

Write-Host ""
Write-Host "==> Helm template render"
Write-Host "    helm template $Release deployment/helm -n $Namespace -f $ScaleValuesPath -f $StrictValuesPath -f $cutoverValuesFile"
& helm template $Release deployment/helm -n $Namespace `
  -f $ScaleValuesPath `
  -f $StrictValuesPath `
  -f $cutoverValuesFile | Out-File -FilePath $helmTemplateOut -Encoding utf8
if ($LASTEXITCODE -ne 0) {
  throw "Helm template render failed with exit code $LASTEXITCODE"
}

$requiredStrictKeys = @(
  "ALLOW_LEGACY_HEADER_AUTH"
  "ASTERISK_BRIDGE_AUTH_MODE"
  "ASTERISK_BRIDGE_AUTH_FALLBACK_LEGACY"
  "VOICE_ADAPTER_TRUSTED_SERVICE_SUBJECTS"
  "RECORDING_IMPORT_TRUSTED_SERVICE_SUBJECTS"
  "RECORDING_IMPORT_ALLOW_ADMIN"
)
foreach ($key in $requiredStrictKeys) {
  if (-not (Select-String -Path $helmTemplateOut -Pattern $key -SimpleMatch)) {
    throw "Rendered manifest does not contain expected strict key: $key"
  }
}

if (-not $Execute) {
  @(
    "Track 9.2 cutover dry-run completed."
    "Artifacts: $artifactsDir"
    "Rendered manifest: $helmTemplateOut"
    "To execute deploy, rerun with -Execute"
  ) | Out-File -FilePath $cutoverSummaryOut -Encoding utf8
  Write-Host ""
  Write-Host "Dry-run completed."
  Write-Host "Artifacts: $artifactsDir"
  Write-Host "Run again with -Execute to apply Helm upgrade."
  exit 0
}

$helmUpgradeArgs = @(
  "helm", "upgrade", "--install", $Release, "deployment/helm", "-n", $Namespace,
  "-f", $ScaleValuesPath,
  "-f", $StrictValuesPath,
  "-f", $cutoverValuesFile
)
if ($ForceUpgrade) {
  $helmUpgradeArgs += "--force"
}
Run-Checked -Label "Helm upgrade/install" -Args $helmUpgradeArgs

Run-Checked -Label "Rollout status: api-gateway" -Args @("kubectl", "-n", $Namespace, "rollout", "status", "deploy/api-gateway")
Run-Checked -Label "Rollout status: asterisk-bridge-service" -Args @("kubectl", "-n", $Namespace, "rollout", "status", "deploy/asterisk-bridge-service")
Run-Checked -Label "Rollout status: voice-adapter-service" -Args @("kubectl", "-n", $Namespace, "rollout", "status", "deploy/voice-adapter-service")
Run-Checked -Label "Rollout status: recording-service" -Args @("kubectl", "-n", $Namespace, "rollout", "status", "deploy/recording-service")

Run-Checked -Label "Helm history (after)" -Args @("helm", "-n", $Namespace, "history", $Release)
& helm -n $Namespace history $Release | Out-File -FilePath $historyAfterOut -Encoding utf8

if (-not $SkipChecks) {
  Run-Checked -Label "Track9 preflight strict" -Args @(
    "python", "scripts/track9_preflight.py",
    "--base-url", $GatewayBaseUrl,
    "--check-sftp",
    "--require-strict-service-auth"
  )
  Run-Checked -Label "Asterisk lab smoke" -Args @(
    "python", "scripts/asterisk_lab_smoke.py",
    "--base-url", $GatewayBaseUrl,
    "--database-url", $DatabaseUrl,
    "--require-recording"
  )
  Run-Checked -Label "Track9 check" -Args @(
    "python", "scripts/track9_check.py",
    "--base-url", $GatewayBaseUrl,
    "--database-url", $DatabaseUrl,
    "--require-recording"
  )
}

$evidenceArgs = @(
  "python", "scripts/track9_collect_evidence.py",
  "--base-url", $GatewayBaseUrl,
  "--database-url", $DatabaseUrl,
  "--run-checks",
  "--require-recording"
)
if ($EvidenceOutDir.Trim()) {
  $evidenceArgs += @("--out-dir", $EvidenceOutDir)
}
Run-Checked -Label "Collect Track9 evidence" -Args $evidenceArgs

$historyLines = Get-Content $historyAfterOut
$deployedLine = $historyLines | Select-String -Pattern "deployed" | Select-Object -Last 1
$rollbackHint = ""
if ($deployedLine) {
  $parts = ($deployedLine.ToString() -split "\s+", [System.StringSplitOptions]::RemoveEmptyEntries)
  if ($parts.Length -ge 1) {
    $currentRevision = $parts[0]
    $previousRevision = [int]$currentRevision - 1
    if ($previousRevision -ge 1) {
      $rollbackHint = "helm -n $Namespace rollback $Release $previousRevision"
    }
  }
}

@(
  "Track 9.2 cutover execution completed."
  "Artifacts: $artifactsDir"
  "Gateway: $GatewayBaseUrl"
  "Database: $DatabaseUrl"
  if ($rollbackHint) { "Rollback command: $rollbackHint" } else { "Rollback command: check helm history manually." }
) | Out-File -FilePath $cutoverSummaryOut -Encoding utf8

Write-Host ""
Write-Host "Track 9.2 cutover completed."
Write-Host "Artifacts: $artifactsDir"
if ($rollbackHint) {
  Write-Host "Rollback hint: $rollbackHint"
}
