# install.ps1 — Windows installer for the restic-manager agent (P2-17).
#
# Usage (Run as administrator):
#   $env:RM_SERVER = "https://restic.lab.example"
#   $env:RM_TOKEN  = "<one-time-token>"  # omit for announce-and-approve
#   iwr "$env:RM_SERVER/install/install.ps1" -UseBasicParsing | iex
#
# What it does:
#   1. checks for admin elevation
#   2. downloads the matching agent binary from the server
#   3. lays down C:\Program Files\restic-manager\ and
#      C:\ProgramData\restic-manager\ (config + state)
#   4. registers the agent as a Windows service via the agent's own
#      `install` subcommand (which uses the SCM API)
#   5. enrolls (token flow if RM_TOKEN set, otherwise announce flow)
#      by spawning the agent with the right CLI flags and waits
#      until config is written
#   6. surfaces (but does NOT disable) any existing scheduled tasks
#      whose name contains "restic" so the operator can decide
#
# Idempotent — safe to re-run.

[CmdletBinding()]
param(
  [string]$Server = $env:RM_SERVER,
  [string]$Token  = $env:RM_TOKEN,
  [string]$InstallDir = 'C:\Program Files\restic-manager',
  [string]$DataDir    = 'C:\ProgramData\restic-manager'
)

$ErrorActionPreference = 'Stop'

function Test-Admin {
  $id  = [System.Security.Principal.WindowsIdentity]::GetCurrent()
  $pri = New-Object System.Security.Principal.WindowsPrincipal($id)
  return $pri.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)
}

function Detect-Arch {
  switch ($env:PROCESSOR_ARCHITECTURE) {
    'AMD64' { return 'amd64' }
    'ARM64' { return 'arm64' }
    default { throw "unsupported PROCESSOR_ARCHITECTURE: $($env:PROCESSOR_ARCHITECTURE)" }
  }
}

function Detect-ResticTasks {
  Write-Host ''
  Write-Host '— Existing restic-named scheduled tasks (review manually) —'
  try {
    $tasks = Get-ScheduledTask -ErrorAction SilentlyContinue |
      Where-Object { $_.TaskName -match 'restic' -or $_.TaskPath -match 'restic' }
    if ($tasks) {
      foreach ($t in $tasks) {
        Write-Host "  * $($t.TaskPath)$($t.TaskName)  state=$($t.State)"
        Write-Host "    Disable with:  Disable-ScheduledTask -TaskName '$($t.TaskName)' -TaskPath '$($t.TaskPath)'"
      }
    } else {
      Write-Host '  (none found)'
    }
  } catch {
    Write-Host '  (Get-ScheduledTask failed; review the Task Scheduler UI manually)'
  }
  Write-Host ''
}

# --- preflight -------------------------------------------------------

if (-not (Test-Admin)) {
  throw 'install.ps1: must be run from an elevated PowerShell (Run as administrator).'
}
if (-not $Server) {
  throw 'install.ps1: -Server (or $env:RM_SERVER) is required, e.g. https://restic.lab.example'
}

$arch = Detect-Arch
Write-Host "install.ps1: server=$Server arch=$arch"

# --- directories -----------------------------------------------------

New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
New-Item -ItemType Directory -Force -Path $DataDir    | Out-Null

# --- download agent --------------------------------------------------

$agentExe = Join-Path $InstallDir 'restic-manager-agent.exe'
$tmpExe   = "$agentExe.tmp"
$dlURL    = "$Server/agent/binary?os=windows&arch=$arch"
Write-Host "install.ps1: downloading $dlURL"
Invoke-WebRequest -UseBasicParsing -Uri $dlURL -OutFile $tmpExe
# Atomic-ish replace: stop service if running so the .exe isn't busy.
try { Stop-Service -Name 'restic-manager-agent' -ErrorAction SilentlyContinue } catch {}
Move-Item -Force -Path $tmpExe -Destination $agentExe

# --- enroll / announce -----------------------------------------------

$cfgPath = Join-Path $DataDir 'agent.yaml'
$args = @('-config', $cfgPath, '-enroll-server', $Server)
if ($Token) {
  $args += @('-enroll-token', $Token)
  Write-Host 'install.ps1: enrolling with one-time token'
} else {
  Write-Host 'install.ps1: no RM_TOKEN — running announce-and-approve flow.'
  Write-Host '  The fingerprint will print below. Compare it with the dashboard before clicking Accept.'
}
& $agentExe @args
if ($LASTEXITCODE -ne 0) {
  throw "install.ps1: agent enrolment failed (exit $LASTEXITCODE)"
}

# --- install + start service ----------------------------------------

# The 'install' subcommand registers the service via the SCM. If
# already registered, it errors loudly — re-run with -Force only if
# you've manually verified.
try {
  & $agentExe install
} catch {
  Write-Host "install.ps1: service may already be registered ($_); continuing."
}
try {
  Start-Service -Name 'restic-manager-agent'
} catch {
  Write-Host "install.ps1: Start-Service failed ($_); check Event Viewer."
}

Detect-ResticTasks

Write-Host ''
Write-Host 'install.ps1: done.'
Write-Host "  config : $cfgPath"
Write-Host "  binary : $agentExe"
Write-Host "  service: restic-manager-agent  (Get-Service to inspect)"
