<#
.SYNOPSIS
  Reference orchestrator: source a GE-Enforce manifest from shopdb, run the
  UNCHANGED engine against it, and report the result back to shopdb.

  This is a thin wrapper around Install-FromManifest.ps1 (the engine). It is a
  reference a site adapts into its GE-Enforce.ps1 flow; it is not the live
  dispatcher. The engine, detection, self-heal, and SMB payload resolution are
  untouched - only the source of the manifest JSON moves from a share file to
  shopdb, plus a result report.

.PARAMETER Scope
  The imaging pc-type / scope name (e.g. gea-shopfloor-cmm), same value the
  dispatcher already resolves from C:\Enrollment\pc-type.txt.

.PARAMETER EnginePath
  Path to Install-FromManifest.ps1 (the engine lib, >= 2.6).

.PARAMETER ShareManifestPath
  The current on-share manifest for this scope. In shadow mode the engine runs
  against THIS (unchanged behavior) and shopdb is only compared + reported. Once
  cut over, omit it and the engine runs against the shopdb-sourced manifest.

.PARAMETER ShadowMode
  Fetch + compare + report, but install from the share (no behavior change).

.NOTES
  Fail-safe: any error exits 0 so a bad web app never blocks or breaks a PC.
  Config comes from HKLM:\SOFTWARE\GE\ShopDB (BaseUrl, ApiToken) - see the psm1.
#>
[CmdletBinding()]
param(
    [Parameter(Mandatory)] [string]$Scope,
    [Parameter(Mandatory)] [string]$EnginePath,
    [string]$ShareManifestPath,
    [switch]$ShadowMode,
    [string]$BaseUrl,
    [string]$ApiToken,
    [string]$LogFile = "C:\Logs\Shopfloor\shopdb-enforce-$(Get-Date -Format yyyyMMdd).log"
)

function Write-Log {
    param([string]$Message, [string]$Level = 'INFO')
    $line = "$(Get-Date -Format 'yyyy-MM-dd HH:mm:ss') [$Level] $Message"
    try { Add-Content -LiteralPath $LogFile -Value $line -ErrorAction SilentlyContinue } catch {}
    Write-Host $line
}

try {
    Import-Module (Join-Path $PSScriptRoot 'ShopdbEnforceClient.psm1') -Force

    $config = Get-ShopdbConfig -BaseUrl $BaseUrl -ApiToken $ApiToken
    if (-not $config) {
        Write-Log 'No shopdb BaseUrl/ApiToken configured yet - retry next cycle.' 'WARN'
        exit 0
    }

    $sync = Sync-ShopdbManifest -Scope $Scope -Config $config
    if (-not $sync.Path) {
        Write-Log "No manifest available for $Scope (shopdb unreachable, no cache)." 'WARN'
        exit 0
    }
    Write-Log "Manifest for $Scope from $($sync.Source) (v$($sync.Version))."

    # Shadow mode: compare shopdb vs the share, but install from the share.
    if ($ShadowMode -and $ShareManifestPath -and (Test-Path $ShareManifestPath)) {
        $diff = Compare-ShopdbShadow -ShopdbManifestPath $sync.Path -ShareManifestPath $ShareManifestPath
        if ($diff.Same) {
            Write-Log 'Shadow: shopdb manifest matches the share.'
        } else {
            Write-Log ("Shadow DIFF: shopdb-only=[{0}] share-only=[{1}] orderDiff={2}" -f `
                ($diff.ShopdbOnly -join ','), ($diff.ShareOnly -join ','), $diff.OrderDiff) 'WARN'
        }
    }

    # Which manifest the engine actually runs against.
    $manifestToRun = if ($ShadowMode -and $ShareManifestPath) { $ShareManifestPath } else { $sync.Path }

    # --- INTEGRATION POINT ---------------------------------------------------
    # Run the engine. Install-FromManifest.ps1 is expected to return (or you
    # adapt it to return) a summary carrying Installed/Skipped/Failed/Filtered
    # and a Results list of @{Name;Action;SelfHealed;ExitCode;Message}. Wire this
    # to your engine's actual return/parse; the shape below is the contract.
    Write-Log "Running engine against $manifestToRun"
    $summary = & $EnginePath -ManifestPath $manifestToRun -PCType $Scope
    if (-not $summary) {
        $summary = @{ Installed = 0; Skipped = 0; Failed = 0; Filtered = 0; Results = @() }
    }
    if (-not $summary.EnforcerVersion) { $summary.EnforcerVersion = '2.6' }

    # Report the result (best-effort).
    $appliedVersion = 0
    if ($sync.Version) { [int]::TryParse($sync.Version, [ref]$appliedVersion) | Out-Null }
    $report = New-ShopdbReport -Scope $Scope -AppliedVersion $appliedVersion -Summary $summary
    if (Send-ShopdbReport -Config $config -Report $report) {
        Write-Log "Reported: installed=$($summary.Installed) skipped=$($summary.Skipped) failed=$($summary.Failed)."
    } else {
        Write-Log 'Report POST failed (non-fatal).' 'WARN'
    }
} catch {
    Write-Log "Unhandled error (non-fatal): $($_.Exception.Message)" 'ERROR'
}
exit 0
