#Requires -Version 5.1

[CmdletBinding()]
param(
    [Parameter(Mandatory = $true)]
    [string] $CutRoot
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

$modulePath = Join-Path $PSScriptRoot 'LegacyCutCoverage.psm1'
$manifestPath = Join-Path $PSScriptRoot 'LegacyCutRequirements.json'
Import-Module -Name $modulePath -Force

if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) {
    throw 'The closed legacy cut requirement manifest is missing.'
}

$manifest = Get-Content -LiteralPath $manifestPath -Raw -Encoding UTF8 | ConvertFrom-Json
if ($manifest.schemaVersion -ne 1 -or
    $manifest.reachableBuilders -le 0 -or
    @($manifest.activeAliases).Count -eq 0 -or
    @($manifest.assets).Count -eq 0) {
    throw 'The closed legacy cut requirement manifest is invalid.'
}

$report = Test-LegacyCutCoverageState `
    -CutRoot $CutRoot `
    -Aliases @($manifest.activeAliases) `
    -AssetRequirements @($manifest.assets) `
    -ReachableBuilders $manifest.reachableBuilders

$failedAliases = @($report.AliasFindings | Where-Object Status -ne 'Present')
$failedAssets = @($report.AssetFindings | Where-Object Status -ne 'Present')
foreach ($finding in $failedAliases) {
    Write-Warning ("CutAlias {0} ({1}) => {2}" -f
        $finding.Alias,
        $finding.RelativePath,
        $finding.Status)
}
foreach ($finding in $failedAssets) {
    Write-Warning ("BuilderAsset {0} {1} ({2}) => {3}" -f
        $finding.Builder,
        $finding.Kind,
        $finding.RelativePath,
        $finding.Status)
}

$report
if ($report.Status -ne 'Passed') {
    $assetSummary = @($failedAssets | ForEach-Object {
        "{0}|{1}|{2}|{3}" -f $_.Builder, $_.Kind, $_.RelativePath, $_.Status
    }) -join '; '
    $messageFormat = "Legacy cut coverage failed. Missing={0}, Unsafe={1}, " +
        "MissingAssets={2}, UnsafeAssets={3}, RootEscapes={4}, " +
        "ReparseAssets={5}. AssetFindings=[{6}]"
    throw ($messageFormat -f
        $report.Missing,
        $report.Unsafe,
        $report.MissingAssets,
        $report.UnsafeAssets,
        $report.RootEscapes,
        $report.ReparseAssets,
        $assetSummary)
}
