#requires -Version 7.0
[CmdletBinding()]
param()
$ErrorActionPreference='Stop'
& "$PSScriptRoot/tests/Test-Workshop.ps1"
$evidencePath=Join-Path $PSScriptRoot 'evidence/verified.json'
if (-not (Test-Path $evidencePath)) { throw 'Verified live evidence is required before building the publication ZIP.' }
$evidence=Get-Content $evidencePath -Raw | ConvertFrom-Json -AsHashtable
foreach ($stage in @('PublicBaseline','PrivateLink','Lockdown','AMA','TestBoundary','TestDnsRecovery','Validate')) {
    if (-not $evidence.Tests[$stage].Passed) { throw "Evidence gate failed: $stage" }
}
$files=@(Get-ChildItem -LiteralPath $PSScriptRoot -File -Recurse | Where-Object { $_.Name -ne 'manifest.sha256' -and $_.Extension -ne '.zip' -and $_.FullName -notmatch '[\\/]__pycache__[\\/]' })
$prohibited=@('(?i)\b[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\b',('(?i)-----'+'BEGIN .*PRIVATE KEY-----'),('Bearer '+'eyJ'),('ssh-rsa '+'AAAA'))
foreach ($file in $files | Where-Object Extension -in @('.ps1','.py','.md','.json','.kql','.txt')) {
    $text=Get-Content -LiteralPath $file.FullName -Raw
    foreach ($pattern in $prohibited) { if ($text -match $pattern) { throw "Privacy scan failed in $($file.Name)" } }
}
$manifest=@($files | Sort-Object FullName | ForEach-Object {
    $relative=[IO.Path]::GetRelativePath($PSScriptRoot,$_.FullName).Replace('\','/')
    "$( (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant() )  $relative"
})
[IO.File]::WriteAllLines((Join-Path $PSScriptRoot 'manifest.sha256'),$manifest,[Text.UTF8Encoding]::new($false))
$files+=Get-Item (Join-Path $PSScriptRoot 'manifest.sha256')
$zipPath=Join-Path (Split-Path $PSScriptRoot) 'azure-monitor-private-link-deep-dive.zip'
# Build to a sibling temporary file, then replace only our own generated ZIP.
$temporary="$zipPath.building"
if (Test-Path $temporary) { throw 'A prior ZIP build is still present; inspect before retrying.' }
$archive=[IO.Compression.ZipFile]::Open($temporary,[IO.Compression.ZipArchiveMode]::Create)
try {
    foreach ($file in $files) {
        $relative=[IO.Path]::GetRelativePath($PSScriptRoot,$file.FullName).Replace('\','/')
        $null=[IO.Compression.ZipFileExtensions]::CreateEntryFromFile($archive,$file.FullName,"azure-monitor-private-link-deep-dive/$relative",[IO.Compression.CompressionLevel]::Optimal)
    }
} finally { $archive.Dispose() }
$check=[IO.Compression.ZipFile]::OpenRead($temporary)
try {
    if ($check.Entries.Count -ne $files.Count -or @($check.Entries | Where-Object FullName -match 'work/|__pycache__|\.key$|state\.json').Count) { throw 'ZIP inventory validation failed.' }
    foreach ($entry in $check.Entries) {
        $stream=$entry.Open();try { $sink=[IO.Stream]::Null;$stream.CopyTo($sink) } finally { $stream.Dispose() }
    }
} finally { $check.Dispose() }
Move-Item -LiteralPath $temporary -Destination $zipPath -Force
Write-Host "PASS: verified ZIP created with $($files.Count) files."
