# Deploy-GEEnforce.ps1
#
# One-shot deploy of the GE-Enforce runtime + scheduled task to an already-
# imaged shopfloor PC. Use this to promote a PC from legacy per-type
# enforcers (CMM-Enforce, Keyence-Enforce, Machine-Enforce, etc.) to the
# unified GE-Enforce, without re-imaging.
#
# Usage (on target PC, as admin):
#   powershell -ExecutionPolicy Bypass -File .\Deploy-GEEnforce.ps1 `
#       -SourceRoot '\\<host>\<share>\enforcer-stage'
#
# The SourceRoot must contain:
#   GE-Enforce.ps1
#   lib\Install-FromManifest.ps1
#
# For imaging-time deployment, Run-ShopfloorSetup.ps1 invokes
# Register-GEEnforce.ps1 directly. This script is specifically for
# retrofitting live PCs.

param(
    [Parameter(Mandatory=$true)]
    [string]$SourceRoot,

    [string]$InstallRoot = 'C:\Program Files\GE\Shopfloor',

    [switch]$TriggerImmediate
)

$ErrorActionPreference = 'Stop'

function Write-DeployLog { param([string]$m) Write-Host "[Deploy-GEEnforce] $m" }

if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole('Administrators')) {
    throw 'Must run as Administrator.'
}

Write-DeployLog "SourceRoot:  $SourceRoot"
Write-DeployLog "InstallRoot: $InstallRoot"

# ---- 1. Validate source ----
$srcEnforcer = Join-Path $SourceRoot 'GE-Enforce.ps1'
$srcLib      = Join-Path $SourceRoot 'lib\Install-FromManifest.ps1'
foreach ($p in @($srcEnforcer, $srcLib)) {
    if (-not (Test-Path -LiteralPath $p)) {
        throw "Missing source file: $p"
    }
}

# ---- 2. Stage runtime ----
Write-DeployLog "Staging runtime to $InstallRoot"
$libDst = Join-Path $InstallRoot 'lib'
foreach ($d in @($InstallRoot, $libDst)) {
    if (-not (Test-Path $d)) { New-Item -Path $d -ItemType Directory -Force | Out-Null }
}
Copy-Item -LiteralPath $srcEnforcer -Destination (Join-Path $InstallRoot 'GE-Enforce.ps1')         -Force
Copy-Item -LiteralPath $srcLib      -Destination (Join-Path $libDst      'Install-FromManifest.ps1') -Force
Write-DeployLog '  Runtime files copied'

# ---- 3. Register scheduled task + unregister legacy ----
$registerScript = Join-Path $SourceRoot 'Register-GEEnforce.ps1'
if (-not (Test-Path -LiteralPath $registerScript)) {
    # Fall back to the copy that should sit next to this deploy script in the
    # repo. In the common rollout, Register-GEEnforce.ps1 lives beside
    # GE-Enforce.ps1 in $SourceRoot.
    $registerScript = Join-Path (Split-Path -Parent $PSCommandPath) 'Register-GEEnforce.ps1'
}
if (-not (Test-Path -LiteralPath $registerScript)) {
    throw "Cannot find Register-GEEnforce.ps1 in $SourceRoot or alongside this script."
}

Write-DeployLog "Invoking $registerScript"
& $registerScript -EnforcerPath (Join-Path $InstallRoot 'GE-Enforce.ps1')

# ---- 4. Optional: trigger one enforce cycle immediately ----
if ($TriggerImmediate) {
    Write-DeployLog 'Triggering GE Shopfloor Enforce now via schtasks /run'
    & schtasks /run /tn 'GE Shopfloor Enforce' | Out-Null
    Start-Sleep -Seconds 3
    $log = Get-ChildItem -Path 'C:\Logs\Shopfloor' -Filter 'enforce-*.log' -ErrorAction SilentlyContinue |
           Sort-Object LastWriteTime -Descending | Select-Object -First 1
    if ($log) {
        Write-DeployLog "Latest log: $($log.FullName) (watching for 30s)"
        $end = (Get-Date).AddSeconds(30)
        $lastSize = 0
        while ((Get-Date) -lt $end) {
            $size = (Get-Item $log.FullName).Length
            if ($size -gt $lastSize) {
                Get-Content -Path $log.FullName -Tail 20 -ErrorAction SilentlyContinue | ForEach-Object { Write-Host "  $_" }
                Write-Host '  ---'
                $lastSize = $size
            }
            Start-Sleep -Seconds 2
        }
    }
}

Write-DeployLog 'DONE. Verify with: schtasks /query /tn "GE Shopfloor Enforce" /v /fo list'
