[CmdletBinding()]
param(
    [Parameter(Mandatory)][string]$Server,
    [ValidateRange(1,65535)][int]$ApiPort = 443,
    [ValidateRange(1,65535)][int]$RelayPort = 7443,
    [Parameter(Mandatory)][string]$ApplicationKey,
    [Parameter(Mandatory)][string]$EnrollmentKey,
    [string]$ServiceName = 'LRM REMOTE DSK Agent',
    [string]$InstallDirectory = "$env:ProgramFiles\LRM REMOTE DSK\Agent",
    [switch]$Silent
)

$ErrorActionPreference = 'Stop'
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { throw 'Administrator privileges are required.' }

function Protect-MachineValue([string]$Value) {
    $bytes = [Text.Encoding]::UTF8.GetBytes($Value)
    [Convert]::ToBase64String([Security.Cryptography.ProtectedData]::Protect($bytes, $null, [Security.Cryptography.DataProtectionScope]::LocalMachine))
}

$serverUrl = ([UriBuilder]::new($(if ($Server -match '^https?://') { $Server } else { "https://$Server" }))).Uri
$builder = [UriBuilder]::new($serverUrl); $builder.Port = $ApiPort
$source = $PSScriptRoot
$exeSource = Join-Path $source 'Lrm.PortMapping.Agent.exe'
if (-not (Test-Path -LiteralPath $exeSource)) { throw "Agent executable not found: $exeSource" }

New-Item -ItemType Directory -Force -Path $InstallDirectory | Out-Null
$service = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($service) { Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue }
Copy-Item -LiteralPath $exeSource -Destination (Join-Path $InstallDirectory 'Lrm.PortMapping.Agent.exe') -Force
Get-ChildItem -LiteralPath $source -Filter '*.json' | Copy-Item -Destination $InstallDirectory -Force

$settingsDirectory = Join-Path $env:ProgramData 'LRM\PortMapping'
New-Item -ItemType Directory -Force -Path $settingsDirectory | Out-Null
$settings = @{ Agent = @{ ServerUrl = $builder.Uri.ToString().TrimEnd('/'); RelayPort = $RelayPort; ProtectedApplicationKey = Protect-MachineValue $ApplicationKey; ProtectedEnrollmentKey = Protect-MachineValue $EnrollmentKey } }
$settings | ConvertTo-Json -Depth 4 | Set-Content -LiteralPath (Join-Path $settingsDirectory 'agent.settings.json') -Encoding UTF8

$exePath = Join-Path $InstallDirectory 'Lrm.PortMapping.Agent.exe'
if (-not $service) { & sc.exe create $ServiceName binPath= "`"$exePath`"" start= auto DisplayName= 'LRM REMOTE DSK Agent' | Out-Null }
& sc.exe failure $ServiceName reset= 86400 actions= restart/5000/restart/15000/restart/60000 | Out-Null
Start-Service -Name $ServiceName
$runKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
New-ItemProperty -Path $runKey -Name 'LRM REMOTE DSK Approval' -PropertyType String -Value "`"$exePath`" --approval-ui" -Force | Out-Null
if (-not $Silent) { Start-Process -FilePath $exePath -ArgumentList '--approval-ui' }
if (-not $Silent) { Write-Host "LRM REMOTE DSK Agent installed and started." -ForegroundColor Green }
