# ArcIn Connector Agent - Windows uninstaller
#
# Fully automated. No manual steps required.
# Removes the service, binary, config, and logs left by install-agent-windows.ps1.
#
# Run as Administrator:
#   powershell -ExecutionPolicy Bypass -File .\uninstall-agent-windows.ps1
#
# To preserve agent.yaml for re-use after reinstall:
#   powershell -ExecutionPolicy Bypass -File .\uninstall-agent-windows.ps1 -KeepConfig

[CmdletBinding()]
param(
    [switch]$KeepConfig
)

$ErrorActionPreference = 'Stop'

$ServiceName = 'ArcInAgent'
$InstallDir  = "$env:ProgramFiles\ArcInAgent"
$ConfigDir   = "$env:ProgramData\ArcInAgent"
$ConfigFile  = Join-Path $ConfigDir 'agent.yaml'

# ── helpers ────────────────────────────────────────────────────────────────────

function Assert-Administrator {
    $id = [Security.Principal.WindowsIdentity]::GetCurrent()
    $p  = New-Object Security.Principal.WindowsPrincipal($id)
    if (-not $p.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Write-Error "ERROR: This script must be run as Administrator. Right-click PowerShell → Run as Administrator."
        exit 1
    }
}

function Write-Step([string]$msg) {
    Write-Host "`n>> $msg" -ForegroundColor Cyan
}

function Write-OK([string]$msg) {
    Write-Host "   OK  $msg" -ForegroundColor Green
}

function Write-Skip([string]$msg) {
    Write-Host "   --  $msg (skipped - not present)" -ForegroundColor DarkGray
}

# ── 1. Stop service ────────────────────────────────────────────────────────────

function Stop-AgentService {
    Write-Step "Stopping service '$ServiceName'"
    $svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
    if (-not $svc) {
        Write-Skip "Service '$ServiceName'"
        return
    }
    if ($svc.Status -ne 'Stopped') {
        Stop-Service -Name $ServiceName -Force -ErrorAction SilentlyContinue
        # Wait up to 10 s for it to stop
        $deadline = (Get-Date).AddSeconds(10)
        while ((Get-Service -Name $ServiceName -ErrorAction SilentlyContinue).Status -ne 'Stopped') {
            if ((Get-Date) -gt $deadline) {
                Write-Warning "   Service did not stop cleanly within 10 s - continuing anyway."
                break
            }
            Start-Sleep -Milliseconds 500
        }
    }
    Write-OK "Service stopped."
}

# ── 2. Delete service ──────────────────────────────────────────────────────────

function Remove-AgentService {
    Write-Step "Removing service '$ServiceName'"
    $svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
    if (-not $svc) {
        Write-Skip "Service '$ServiceName'"
        return
    }
    $result = & sc.exe delete $ServiceName 2>&1
    if ($LASTEXITCODE -ne 0) {
        Write-Warning "   sc.exe delete returned exit code $LASTEXITCODE : $result"
        Write-Warning "   Attempting removal via WMI as fallback..."
        $wmiSvc = Get-WmiObject -Class Win32_Service -Filter "Name='$ServiceName'" -ErrorAction SilentlyContinue
        if ($wmiSvc) { [void]$wmiSvc.Delete() }
    }
    # Wait up to 15 s for SCM to confirm removal
    $deadline = (Get-Date).AddSeconds(15)
    while (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) {
        if ((Get-Date) -gt $deadline) {
            Write-Warning "   Service entry still visible after 15 s. A reboot may be needed to fully purge it."
            break
        }
        Start-Sleep -Milliseconds 500
    }
    Write-OK "Service removed."
}

# ── 3. Remove install directory ────────────────────────────────────────────────

function Remove-InstallDir {
    Write-Step "Removing install directory: $InstallDir"
    if (-not (Test-Path $InstallDir)) {
        Write-Skip $InstallDir
        return
    }
    # Take ownership + grant full control so Remove-Item cannot be blocked by ACLs
    & takeown  /F "$InstallDir" /R /D Y 2>&1 | Out-Null
    & icacls   "$InstallDir" /grant Administrators:F /T /C /Q 2>&1 | Out-Null
    Remove-Item -Recurse -Force -Path $InstallDir -ErrorAction Stop
    Write-OK "Removed: $InstallDir"
}

# ── 4. Remove config directory ─────────────────────────────────────────────────

function Remove-ConfigDir {
    Write-Step "Removing config directory: $ConfigDir"
    if (-not (Test-Path $ConfigDir)) {
        Write-Skip $ConfigDir
        return
    }

    # Reset ACL on the whole config dir (install script hardened agent.yaml)
    & takeown /F "$ConfigDir" /R /D Y 2>&1 | Out-Null
    & icacls  "$ConfigDir" /grant Administrators:F /T /C /Q 2>&1 | Out-Null

    if ($KeepConfig -and (Test-Path $ConfigFile)) {
        Write-Host "   Preserving $ConfigFile (-KeepConfig set)" -ForegroundColor Yellow
        # Remove everything except agent.yaml
        Get-ChildItem $ConfigDir -Exclude 'agent.yaml' | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
        Write-OK "Config directory cleaned (agent.yaml preserved)."
    } else {
        Remove-Item -Recurse -Force -Path $ConfigDir -ErrorAction Stop
        Write-OK "Removed: $ConfigDir"
    }
}

# ── 5. Summary ─────────────────────────────────────────────────────────────────

function Show-Summary {
    Write-Host ""
    Write-Host "============================================" -ForegroundColor Green
    Write-Host "  Uninstall complete." -ForegroundColor Green
    Write-Host "============================================" -ForegroundColor Green

    # Verify nothing was left behind
    $leftovers = @()
    if (Get-Service -Name $ServiceName -ErrorAction SilentlyContinue) { $leftovers += "Service: $ServiceName (may need reboot to purge)" }
    if (Test-Path $InstallDir)                                         { $leftovers += "Directory: $InstallDir" }
    if (-not $KeepConfig -and (Test-Path $ConfigDir))                  { $leftovers += "Directory: $ConfigDir" }

    if ($leftovers.Count -eq 0) {
        Write-Host "  All artifacts removed successfully." -ForegroundColor Green
    } else {
        Write-Host "  The following items could not be fully removed:" -ForegroundColor Yellow
        $leftovers | ForEach-Object { Write-Host "    - $_" -ForegroundColor Yellow }
        Write-Host "  A system reboot should clear any remaining entries." -ForegroundColor Yellow
    }

    if ($KeepConfig -and (Test-Path $ConfigFile)) {
        Write-Host ""
        Write-Host "  Config preserved at: $ConfigFile" -ForegroundColor Cyan
        Write-Host "  Run install-agent-windows.ps1 when ready to reinstall." -ForegroundColor Cyan
    }
    Write-Host ""
}

# ── Main ───────────────────────────────────────────────────────────────────────

Assert-Administrator
Stop-AgentService
Remove-AgentService
Remove-InstallDir
Remove-ConfigDir
Show-Summary
