[CmdletBinding()]
param(
    [string]$ConfigPath = 'C:\ProgramData\AWatch-rus\deployment-config.json',
    [ValidateSet('shadow', 'enforce')]
    [string]$Mode = 'shadow',
    [string]$ServiceName = 'AWatchRusCollectorGuard',
    [int]$LoopSeconds = 60,
    [switch]$DisableRecoveryTask
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

function Assert-Admin {
    $id = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = [Security.Principal.WindowsPrincipal]::new($id)
    if (-not $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        throw 'Run as Administrator.'
    }
}

Assert-Admin

$guardScriptPath = Join-Path $PSScriptRoot 'aw-collector-guard.ps1'
$rustTelemetryPath = Join-Path $PSScriptRoot 'aw-windows-telemetry.exe'
$serviceSourcePath = Join-Path $PSScriptRoot 'AWatchRusCollectorGuardService.cs'
$serviceExePath = Join-Path $PSScriptRoot 'AWatchRusCollectorGuardService.exe'
if (-not (Test-Path -LiteralPath $rustTelemetryPath) -and -not (Test-Path -LiteralPath $guardScriptPath)) {
    throw "Neither Rust collector guard nor PowerShell fallback was found: $rustTelemetryPath ; $guardScriptPath"
}
if (-not (Test-Path -LiteralPath $serviceSourcePath)) {
    throw "Collector guard service source not found: $serviceSourcePath"
}
if (-not (Test-Path -LiteralPath $ConfigPath)) {
    throw "Config not found: $ConfigPath"
}

$cscCandidates = @(
    (Join-Path $env:WINDIR 'Microsoft.NET\Framework64\v4.0.30319\csc.exe'),
    (Join-Path $env:WINDIR 'Microsoft.NET\Framework\v4.0.30319\csc.exe')
)
$csc = @($cscCandidates | Where-Object { Test-Path -LiteralPath $_ } | Select-Object -First 1)
if (-not $csc) {
    throw 'C# compiler not found. Install .NET Framework build tools or provide AWatchRusCollectorGuardService.exe.'
}

$existing = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
if ($existing) {
    if ($existing.Status -ne 'Stopped') {
        Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
        try {
            $existing.WaitForStatus('Stopped', [TimeSpan]::FromSeconds(20))
        }
        catch {
        }
    }
    sc.exe delete $ServiceName | Out-Null
    Start-Sleep -Seconds 2
}

& $csc /nologo /target:exe /optimize+ /out:$serviceExePath /reference:System.ServiceProcess.dll $serviceSourcePath | Out-Null
if ($LASTEXITCODE -ne 0 -or -not (Test-Path -LiteralPath $serviceExePath)) {
    throw "Failed to compile $serviceExePath"
}

$logsRoot = Join-Path (Split-Path -Path $ConfigPath -Parent) 'logs'
$serviceLogPath = Join-Path $logsRoot 'collector-guard-service.log'
if (Test-Path -LiteralPath $rustTelemetryPath) {
    $rustArgs = "collector-guard --config-path `"$ConfigPath`" --mode $Mode --loop-seconds $LoopSeconds"
    $binPath = "`"$serviceExePath`" --service-name `"$ServiceName`" --exec `"$rustTelemetryPath`" --args `"$rustArgs`" --log `"$serviceLogPath`""
}
else {
    if (-not (Test-Path -LiteralPath $guardScriptPath)) {
        throw "Collector guard script not found: $guardScriptPath"
    }
    $binPath = "`"$serviceExePath`" --service-name `"$ServiceName`" --script `"$guardScriptPath`" --config `"$ConfigPath`" --mode $Mode --loop $LoopSeconds --log `"$serviceLogPath`""
}

New-Service -Name $ServiceName -BinaryPathName $binPath -DisplayName 'AWatch-rus Collector Guard' -StartupType Automatic | Out-Null
sc.exe description $ServiceName "Session-aware ActivityWatch collector guard for AWatch-rus" | Out-Null
sc.exe failure $ServiceName reset= 300 actions= restart/5000/restart/15000/restart/60000 | Out-Null

if ($DisableRecoveryTask) {
    Write-Warning 'DisableRecoveryTask is deprecated and ignored: ActivityWatch Recovery must remain enabled as collector guard fallback.'
}
else {
    try {
        Enable-ScheduledTask -TaskName 'ActivityWatch Recovery' -ErrorAction SilentlyContinue | Out-Null
    }
    catch {
    }
}

sc.exe start $ServiceName | Out-Null

Write-Output "Collector guard service installed: $ServiceName"
Write-Output "Mode: $Mode"
Write-Output "Config: $ConfigPath"
Write-Output "Runtime: $(if (Test-Path -LiteralPath $rustTelemetryPath) { 'rust' } else { 'powershell' })"
