# Repair Siraya Printer Service (restart service, task fallback, probe health, open setup UI).
param(
  [Parameter(Mandatory = $true)]
  [string]$BundleRoot
)

$ErrorActionPreference = "Stop"
$LogFile = Join-Path $env:TEMP "SirayaPrinter-Repair.log"
$InstallDir = Join-Path $env:ProgramFiles "Siraya\Printer"
$DataDir = Join-Path $env:ProgramData "Siraya\Printer"
$StartBat = Join-Path $InstallDir "start-agent.bat"

function Write-Log {
  param([string]$Message)
  $line = "[$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')] $Message"
  Add-Content -Path $LogFile -Value $line
  Write-Host $Message
}

function Get-PersistenceMode {
  $file = Join-Path $DataDir "persistence.json"
  if (-not (Test-Path -LiteralPath $file)) { return "service" }
  try {
    $json = Get-Content -LiteralPath $file -Raw | ConvertFrom-Json
    if ($json.mode -eq "scheduled-task") { return "scheduled-task" }
  } catch { }
  return "service"
}

function Stop-AgentUnified {
  $stopScript = Join-Path $PSScriptRoot "stop-agent.ps1"
  if (-not (Test-Path -LiteralPath $stopScript)) {
    $stopScript = Join-Path $InstallDir "installer\windows\stop-agent.ps1"
  }
  if (Test-Path -LiteralPath $stopScript) {
    . $stopScript
    Stop-SirayaPrinterAgent -Log { param($Message) Write-Log $Message }
    return
  }
  try { schtasks /End /TN "SirayaPrinterAgent" 2>$null | Out-Null } catch { }
  try { net.exe stop SirayaPrinterService 2>$null | Out-Null } catch { }
}

function Get-HealthCheckPorts {
  return @(5000)
}

function Find-HealthPort {
  param([int]$TimeoutSec = 90)
  $deadline = (Get-Date).AddSeconds($TimeoutSec)
  do {
    foreach ($port in Get-HealthCheckPorts) {
      $url = "http://127.0.0.1:$port/health"
      try {
        $r = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 3
        if ($r.StatusCode -eq 200) {
          return $port
        }
      } catch { }
    }
    Start-Sleep -Seconds 2
  } while ((Get-Date) -lt $deadline)
  return $null
}

function Ensure-StartBat {
  if (Test-Path -LiteralPath $StartBat) { return }
  $content = @(
    '@echo off',
    'cd /d "%~dp0"',
    '"%~dp0runtime\node.exe" "%~dp0index.js"'
  ) -join "`r`n"
  Set-Content -LiteralPath $StartBat -Value $content -Encoding ASCII
  Write-Log "Created start-agent.bat"
}

function Get-TaskRunAsUser {
  if ($env:USERDOMAIN -and $env:USERNAME) {
    return "$env:USERDOMAIN\$env:USERNAME"
  }
  return $env:USERNAME
}

function Start-AgentFallback {
  Ensure-StartBat
  $runAs = Get-TaskRunAsUser
  Write-Log "Starting via start-agent.bat (current user)..."
  Start-Process -FilePath $StartBat -WindowStyle Hidden
  Start-Sleep -Seconds 5
  $port = Find-HealthPort -TimeoutSec 45
  if ($port) {
    schtasks /Delete /TN "SirayaPrinterAgent" /F 2>$null | Out-Null
    schtasks /Create /TN "SirayaPrinterAgent" /TR "`"$StartBat`"" /SC ONLOGON /RU $runAs /RL HIGHEST /F | Out-Null
    return $port
  }
  Write-Log "WARN: start-agent.bat did not bring up health quickly"
  return (Find-HealthPort -TimeoutSec 45)
}

try {
  $BundleRoot = $BundleRoot.Trim().TrimEnd('\', '/')
  if ($BundleRoot) {
    $BundleRoot = (Resolve-Path -LiteralPath $BundleRoot).Path
  }
  Write-Log "Siraya Printer repair"
  Write-Log "Log file: $LogFile"
  Write-Log "Service logs: $env:ProgramData\Siraya\Printer\logs\"

  if (-not (Test-Path -LiteralPath (Join-Path $InstallDir "index.js"))) {
    throw "Siraya Printer not installed at $InstallDir. Run Install.cmd first."
  }

  $port = Find-HealthPort -TimeoutSec 5
  if ($port) {
    Write-Log "Agent already healthy on port $port"
    Start-Process "http://127.0.0.1:$port/"
    Write-Log "Repair succeeded."
    exit 0
  }

  $mode = Get-PersistenceMode
  Write-Log "Persistence mode: $mode"
  Stop-AgentUnified
  Start-Sleep -Seconds 2

  if ($mode -eq "scheduled-task") {
    $port = Start-AgentFallback
  } else {
    $svc = Get-Service -Name SirayaPrinterService -ErrorAction SilentlyContinue
    if ($svc) {
      Write-Log "Restarting SirayaPrinterService..."
      & net.exe start SirayaPrinterService 2>$null | Out-Null
      $port = Find-HealthPort -TimeoutSec 60
    }
    if (-not $port) {
      Write-Log "Service restart did not bring up health - trying scheduled task fallback..."
      $port = Start-AgentFallback
    }
  }

  if (-not $port) {
    Write-Log "Check: $env:ProgramData\Siraya\Printer\logs\error.log"
    throw "Print agent did not respond on http://127.0.0.1:5000/health. Reboot and run Install.cmd. See $LogFile"
  }

  $setupUrl = "http://127.0.0.1:$port"
  Write-Log "Health OK at $setupUrl"
  Start-Process $setupUrl
  Write-Log "Repair succeeded."
  exit 0
} catch {
  Write-Log "ERROR: $($_.Exception.Message)"
  exit 1
}
