<#
.SYNOPSIS
  GuruRMM enrollment: install Tailscale on a Windows client machine and join the
  CLIENT's tailnet unattended, using a pre-authorized tagged auth key.

.DESCRIPTION
  Idempotent and safe to re-run. Designed to run as SYSTEM from GuruRMM with ZERO
  end-user interaction:
    1. Installs the Tailscale MSI silently in unattended mode (stays connected even
       when no user is logged in - TS_UNATTENDEDMODE=always).
    2. Authenticates with a pre-auth key. The device's tag + identity come from the
       key, so there is no interactive IdP login for the (tech-inept) user to do.
  For a "the machines just need to see each other" setup it advertises NO routes and
  is NOT an exit node - each box is simply a node on the tailnet.

.PARAMETER AuthKey
  Pre-auth key from the CLIENT's tailnet (Admin console -> Settings -> Keys ->
  Generate auth key). Generate it as:
     [x] Reusable      - enroll multiple machines / tolerate re-runs
     [x] Pre-approved  - skip manual device approval
     [x] Tags: tag:<client>   - node inherits the tag; not tied to a user login
     Expiry: ~90 days is fine for an onboarding window; rotate afterward.
  Pass this into GuruRMM as a SECRET/masked parameter. NEVER hardcode it here.

.PARAMETER Hostname
  Name the device shows as on the tailnet. Defaults to the Windows computer name.

.PARAMETER MsiUrl
  Tailscale stable MSI. Defaults to the rolling "latest" stable. Pin a version if
  you want deterministic installs (see https://pkgs.tailscale.com/stable/#windows).

.PARAMETER LoginServer
  Custom coordination server. Leave blank for Tailscale's default (SaaS).

.NOTES
  tailscale.exe lives at C:\Program Files\Tailscale\tailscale.exe after install.
  Exit 0 = node is up on the tailnet. Exit 1 = failed (check the key + connectivity).
#>
param(
  [Parameter(Mandatory = $true)][string]$AuthKey,
  [string]$Hostname    = $env:COMPUTERNAME,
  [string]$MsiUrl      = 'https://pkgs.tailscale.com/stable/tailscale-setup-latest-amd64.msi',
  [string]$LoginServer = ''
)

$ErrorActionPreference = 'Stop'
$ts = "$env:ProgramFiles\Tailscale\tailscale.exe"
function Log($m) { Write-Output "[tailscale-enroll] $m" }

# 1. Install Tailscale if absent (silent, unattended, no GUI popup) ----------------
if (-not (Test-Path $ts)) {
  Log "Tailscale not present - downloading MSI from $MsiUrl"
  $msi = Join-Path $env:TEMP 'tailscale-setup.msi'
  [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
  Invoke-WebRequest -Uri $MsiUrl -OutFile $msi -UseBasicParsing
  Log "Installing MSI (TS_UNATTENDEDMODE=always, no GUI launch)"
  $msiArgs = "/i `"$msi`" /quiet /norestart TS_UNATTENDEDMODE=always TS_NOLAUNCH=true"
  $p = Start-Process msiexec.exe -ArgumentList $msiArgs -Wait -PassThru
  if ($p.ExitCode -ne 0 -and $p.ExitCode -ne 3010) { throw "MSI install failed (msiexec exit $($p.ExitCode))" }
  Remove-Item $msi -ErrorAction SilentlyContinue
  Start-Sleep -Seconds 5
} else {
  Log "Tailscale already installed: $(((& $ts version) -split "`n")[0])"
}
if (-not (Test-Path $ts)) { throw "tailscale.exe not found after install" }

# 2. Already connected? (idempotent - re-runs are a no-op) -------------------------
try { $cur = (& $ts status --json 2>$null | ConvertFrom-Json) } catch { $cur = $null }
if ($cur -and $cur.BackendState -eq 'Running' -and $cur.Self.TailscaleIPs) {
  Log "Already connected as $($cur.Self.HostName) ($($cur.Self.TailscaleIPs -join ', ')) - nothing to do"
  & $ts status
  exit 0
}

# 3. Bring it up with the pre-auth key (tag + identity come FROM the key) ----------
#    No --advertise-routes / --advertise-exit-node: peer-to-peer only.
$up = @('up', '--authkey', $AuthKey, '--hostname', $Hostname, '--accept-dns=true')
if ($LoginServer) { $up += "--login-server=$LoginServer" }
Log "Joining tailnet as '$Hostname'"
& $ts @up
Start-Sleep -Seconds 3

# 4. Verify + report the 100.x address for the RMM job output ----------------------
try { $st = (& $ts status --json 2>$null | ConvertFrom-Json) } catch { $st = $null }
if ($st -and $st.BackendState -eq 'Running' -and $st.Self.TailscaleIPs) {
  Log "SUCCESS - $($st.Self.HostName) is on the tailnet at $($st.Self.TailscaleIPs -join ', ')"
  & $ts status
  exit 0
} else {
  Log "FAILED - backend state: $(if($st){$st.BackendState}else{'unknown'})."
  Log "Check the auth key (expired / not reusable / not pre-approved) and outbound connectivity to *.tailscale.com:443 + UDP 41641."
  exit 1
}
