<#
.SYNOPSIS
    Phase 6.4 exit-gate compliance check. Each check either passes or records a
    failure; non-zero exit = fail.

.DESCRIPTION
    Validates Phase 6.4 (Admin UI completion) progress. Checks enumerated in
    `docs/v2/implementation/phase-6-4-admin-ui-completion.md`
    §"Compliance Checks (run at exit gate)".

.NOTES
    Usage:  pwsh ./scripts/compliance/phase-6-4-compliance.ps1
    Exit:   0 = all checks passed; non-zero = one or more FAILs
#>
[CmdletBinding()]
param()

$ErrorActionPreference = 'Stop'
$script:failures = 0
$repoRoot = (Resolve-Path (Join-Path $PSScriptRoot '..\..')).Path

function Assert-Pass { param([string]$C) Write-Host "  [PASS] $C" -ForegroundColor Green }
function Assert-Fail { param([string]$C, [string]$R) Write-Host "  [FAIL] $C - $R" -ForegroundColor Red; $script:failures++ }
function Assert-Deferred { param([string]$C, [string]$P) Write-Host "  [DEFERRED] $C  (follow-up: $P)" -ForegroundColor Yellow }

function Assert-FileExists {
    param([string]$C, [string]$P)
    if (Test-Path (Join-Path $repoRoot $P)) { Assert-Pass "$C  ($P)" }
    else { Assert-Fail $C "missing file: $P" }
}

function Assert-TextFound {
    param([string]$C, [string]$Pat, [string[]]$Paths)
    foreach ($p in $Paths) {
        $full = Join-Path $repoRoot $p
        if (-not (Test-Path $full)) { continue }
        if (Select-String -Path $full -Pattern $Pat -Quiet) {
            Assert-Pass "$C  (matched in $p)"
            return
        }
    }
    Assert-Fail $C "pattern '$Pat' not found in any of: $($Paths -join ', ')"
}

Write-Host ""
Write-Host "=== Phase 6.4 compliance - Admin UI completion ===" -ForegroundColor Cyan
Write-Host ""

Write-Host "Stream A data layer - UnsImpactAnalyzer"
Assert-FileExists "UnsImpactAnalyzer present" "src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/UnsImpactAnalyzer.cs"
Assert-TextFound "DraftRevisionToken present" "record DraftRevisionToken" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/UnsImpactAnalyzer.cs")
Assert-TextFound "Cross-cluster move rejected per decision #82" "CrossClusterMoveRejectedException" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/UnsImpactAnalyzer.cs")
Assert-TextFound "LineMove + AreaRename + LineMerge covered" "UnsMoveKind\.LineMerge" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/UnsImpactAnalyzer.cs")

Write-Host ""
Write-Host "Stream B data layer - EquipmentCsvImporter"
Assert-FileExists "EquipmentCsvImporter present" "src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs"
Assert-TextFound "CSV header version marker '# OtOpcUaCsv v1'" "OtOpcUaCsv v1" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")
Assert-TextFound "Required columns match decision #117" "ZTag.+MachineCode.+SAPID.+EquipmentId.+EquipmentUuid" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")
Assert-TextFound "Optional columns match decision #139 (Manufacturer)" "Manufacturer" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")
Assert-TextFound "Optional columns include DeviceManualUri" "DeviceManualUri" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")
Assert-TextFound "Rejects duplicate ZTag within file" "Duplicate ZTag" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")
Assert-TextFound "Rejects unknown column" "unknown column" @("src/Server/ZB.MOM.WW.OtOpcUa.Admin/Services/EquipmentCsvImporter.cs")

Write-Host ""
Write-Host "Deferred surfaces"
Assert-Deferred "Stream A UI - UnsTab MudBlazor drag/drop + 409 modal + Playwright" "task #153"
Assert-Deferred "Stream B follow-up - EquipmentImportBatch staging + FinaliseImportBatch + CSV import UI" "task #155"
Assert-Deferred "Stream C - DiffViewer refactor + 6 section plugins + 1000-row cap" "task #156"
Assert-Deferred "Stream D - IdentificationFields.razor + DriverNodeManager OPC 40010 sub-folder" "task #157"

Write-Host ""
Write-Host "Cross-cutting"
Write-Host "  Running full solution test suite..." -ForegroundColor DarkGray
$prevPref = $ErrorActionPreference
$ErrorActionPreference = 'Continue'
$testOutput = & dotnet test (Join-Path $repoRoot 'ZB.MOM.WW.OtOpcUa.slnx') --nologo 2>&1
$ErrorActionPreference = $prevPref
$passLine = $testOutput | Select-String 'Passed:\s+(\d+)' -AllMatches
$failLine = $testOutput | Select-String 'Failed:\s+(\d+)' -AllMatches
$passCount = 0; foreach ($m in $passLine.Matches) { $passCount += [int]$m.Groups[1].Value }
$failCount = 0; foreach ($m in $failLine.Matches) { $failCount += [int]$m.Groups[1].Value }
$baseline = 1137
if ($passCount -ge $baseline) { Assert-Pass "No test-count regression ($passCount >= $baseline pre-Phase-6.4 baseline)" }
else { Assert-Fail "Test-count regression" "passed $passCount < baseline $baseline" }

if ($failCount -le 1) { Assert-Pass "No new failing tests (pre-existing CLI flake tolerated)" }
else { Assert-Fail "New failing tests" "$failCount failures > 1 tolerated" }

Write-Host ""
if ($script:failures -eq 0) {
    Write-Host "Phase 6.4 compliance: PASS" -ForegroundColor Green
    exit 0
}
Write-Host "Phase 6.4 compliance: $script:failures FAIL(s)" -ForegroundColor Red
exit 1
