param(
    [string]$Stamp = (Get-Date).ToString("yyyy-MM-dd")
)

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

function Get-NormalizedRepoId {
    param(
        [string]$RepoUrl,
        [string]$FallbackName
    )

    if ($RepoUrl) {
        $trimmed = $RepoUrl.Trim()
        if ($trimmed -match '^(?:https?|ssh)://[^/]+/(?<id>.+?)(?:\.git)?/?$') {
            return $Matches["id"]
        }
        if ($trimmed -match '^[^:]+:(?<id>.+?)(?:\.git)?/?$') {
            return $Matches["id"]
        }
    }

    if ($FallbackName) {
        return ($FallbackName -replace '\s*-\s*', '/' -replace '\s+', '-')
    }

    return "unknown"
}

function Get-GitRoot {
    param([string]$Path)

    try {
        $root = (git -C $Path rev-parse --show-toplevel 2>$null)
        if ($LASTEXITCODE -eq 0 -and $root) {
            return $root.Trim()
        }
    } catch {
    }

    return $null
}

function Get-RemoteOriginUrl {
    param([string]$Path)

    try {
        $remote = (git -C $Path config --get remote.origin.url 2>$null)
        if ($LASTEXITCODE -eq 0 -and $remote) {
            return $remote.Trim()
        }
    } catch {
    }

    return ""
}

function Test-StandaloneGitRoot {
    param(
        [string]$Path,
        [string]$GitRoot
    )

    if (-not $GitRoot) {
        return $false
    }

    return ([System.IO.Path]::GetFullPath($GitRoot).TrimEnd('\') -eq
        [System.IO.Path]::GetFullPath($Path).TrimEnd('\'))
}

function Get-RootFilesByPattern {
    param(
        [string]$Path,
        [string]$Pattern
    )

    return @(Get-ChildItem -LiteralPath $Path -File -ErrorAction SilentlyContinue |
        Where-Object { $_.Name -match $Pattern })
}

function Get-LicenseSignalFromText {
    param(
        [string]$FileName,
        [string]$Text
    )

    $name = $FileName.ToUpperInvariant()
    if ($name -match 'MIT' -or
        (($Text -match 'Permission is hereby granted, free of charge, to any person obtaining a copy') -and
            ($Text -match 'THE SOFTWARE IS PROVIDED "AS IS"'))) {
        return "MIT"
    }

    if ($name -match 'APACHE' -or $Text -match 'Apache License' -or $Text -match 'Apache-2\.0') {
        return "Apache-2.0"
    }

    if ($name -match 'MPL' -or $Text -match 'Mozilla Public License' -or $Text -match 'MPL-2\.0') {
        return "MPL-2.0"
    }

    $trimmedText = $Text.TrimStart()

    if ($name -match 'AGPL' -or $trimmedText -match '^[#\s]*GNU AFFERO GENERAL PUBLIC LICENSE') {
        return "AGPL-3.0"
    }

    if ($name -match 'GPL' -or $trimmedText -match '^[#\s]*GNU GENERAL PUBLIC LICENSE') {
        return "GPL-3.0-or-later"
    }

    if ($name -match 'BSD' -or $Text -match 'Redistribution and use in source and binary forms') {
        return "BSD-family"
    }

    if ($name -match 'ISC' -or $Text -match 'ISC License') {
        return "ISC"
    }

    if ($name -match 'POLYFORM' -or $Text -match 'PolyForm') {
        return "PolyForm-family"
    }

    if ($name -match 'BUSINESS' -or $Text -match 'Business Source License' -or $Text -match '\bBSL\b') {
        return "BSL"
    }

    if ($Text -match 'Custom broad-use license') {
        return "custom-broad-use"
    }

    return "other_root_license_file"
}

function Resolve-RootLicenseSignal {
    param([array]$LicenseFileRows)

    $signals = @($LicenseFileRows | Select-Object -ExpandProperty Signal -Unique)
    if (@($signals).Count -eq 0) {
        return ""
    }

    if (($signals -contains "MPL-2.0") -and
        @($signals | Where-Object { $_ -like "GPL*" -or $_ -like "AGPL*" }).Count -gt 0) {
        return "MPL-2.0 OR GPL-3.0-or-later"
    }

    if (($signals -contains "MIT") -and ($signals -contains "Apache-2.0")) {
        return "MIT OR Apache-2.0"
    }

    if (($signals -contains "MIT") -and @($signals | Where-Object { $_ -like "GPL*" -or $_ -like "AGPL*" }).Count -gt 0) {
        return "MIT with GPL-family companion file"
    }

    return ($signals -join " + ")
}

function Get-MetadataSignal {
    param(
        [string]$Path,
        [string]$ManifestLicense
    )

    $candidates = @("package.json", "Cargo.toml", "pyproject.toml", "setup.cfg", "setup.py", "composer.json")
    foreach ($candidate in $candidates) {
        $fullPath = Join-Path $Path $candidate
        if (-not (Test-Path -LiteralPath $fullPath)) {
            continue
        }

        $text = Get-Content -LiteralPath $fullPath -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
        if (-not $text) {
            continue
        }

        if ($candidate -eq "package.json") {
            try {
                $packageJson = $text | ConvertFrom-Json -ErrorAction Stop
                $packageLicense = [string]$packageJson.license
                if ($packageLicense) {
                    $packageLicense = $packageLicense.Trim()
                    if ($packageLicense -and
                        $packageLicense -notmatch '^SEE LICENSE IN\b' -and
                        ((-not $ManifestLicense) -or
                            ($ManifestLicense -match [regex]::Escape($packageLicense)) -or
                            ($packageLicense -match [regex]::Escape($ManifestLicense)))) {
                        return @{
                            Signal = $packageLicense
                            Path = $candidate
                        }
                    }
                }
            } catch {
            }
        }

        if ($ManifestLicense -match 'MIT' -and $text -match '\bMIT\b') {
            return @{
                Signal = "MIT"
                Path = $candidate
            }
        }
    }

    return $null
}

function Get-CopyrightLine {
    param([string]$Text)

    foreach ($line in ($Text -split "`r?`n")) {
        if ($line -match 'copyright') {
            return $line.Trim()
        }
    }

    return ""
}

function Get-MITTextSource {
    param([array]$LicenseFileRows)

    foreach ($row in $LicenseFileRows) {
        if ($row.Signal -eq "MIT") {
            return $row
        }
    }

    foreach ($row in $LicenseFileRows) {
        if ($row.Text -match 'MIT License') {
            return $row
        }
    }

    return $null
}

function Get-SafeFileStem {
    param([string]$RepoId)

    $stem = $RepoId -replace '[\\/:\*\?"<>\| ]', '__'
    return $stem.Trim('_')
}

function Write-Utf8NoBomTextFile {
    param(
        [string]$Path,
        [string]$Content
    )

    $encoding = [System.Text.UTF8Encoding]::new($false)
    [System.IO.File]::WriteAllText($Path, $Content, $encoding)
}

$repoRoot = Split-Path -Parent $PSScriptRoot
$docsRoot = Join-Path $repoRoot "docs"
$generatedRoot = Join-Path $docsRoot "generated\\license_audit"
$manifestPath = "C:\\Workspaces\\HyperTwist\\repos.manifest.json"
$legacyMirrorsRoot = Join-Path $repoRoot "mirrors"
$csvPath = Join-Path $generatedRoot "HYPERTWIST_REPO_LICENSE_EVIDENCE_AUDIT_$Stamp.csv"
$markdownPath = Join-Path $docsRoot "HYPERTWIST_REPO_LICENSE_EVIDENCE_AUDIT_$Stamp.md"
$mitTextDir = Join-Path $generatedRoot "MIT_LICENSE_TEXTS_$Stamp"
$thirdPartyPath = Join-Path $generatedRoot "THIRD_PARTY_NOTICES_MIT_DRAFT_$Stamp.txt"

$canonicalMitText = @"
MIT License

[README-only or metadata-only MIT signal captured by HyperTwist legal audit.
No standalone root MIT LICENSE file was present in the repo-local mirror at the
recorded commit. Preserve the evidence path, source URL, and commit hash from
the paired audit ledger and third-party notices draft.]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"@

New-Item -ItemType Directory -Path $generatedRoot -Force | Out-Null
New-Item -ItemType Directory -Path $mitTextDir -Force | Out-Null
Get-ChildItem -LiteralPath $mitTextDir -File -ErrorAction SilentlyContinue | Remove-Item -Force

$manifest = Get-Content $manifestPath -Raw -Encoding UTF8 | ConvertFrom-Json
$entries = New-Object System.Collections.Generic.List[object]

foreach ($repo in $manifest.repositories) {
    if ($repo.localPath -like 'C:\Workspaces\HyperTwist\mirrors\*') {
        $entries.Add([pscustomobject]@{
                RepoId = Get-NormalizedRepoId -RepoUrl $repo.repoUrl -FallbackName $repo.name
                RepoUrl = $repo.repoUrl
                PrimaryPath = $repo.localPath
                AllLocalPaths = @($repo.localPath)
                CurrentManifestMirrorClass = $repo.mirrorClass
                CurrentManifestLicense = $repo.license
                CurrentManifestLicenseStatus = $repo.licenseStatus
                Source = "manifest"
            })
    }
}

if (Test-Path -LiteralPath $legacyMirrorsRoot) {
    $legacyDirs = @(Get-ChildItem -LiteralPath $legacyMirrorsRoot -Directory -ErrorAction SilentlyContinue)
    foreach ($legacyDir in $legacyDirs) {
        $gitRoot = Get-GitRoot -Path $legacyDir.FullName
        if (-not (Test-StandaloneGitRoot -Path $legacyDir.FullName -GitRoot $gitRoot)) {
            continue
        }

        $repoUrl = Get-RemoteOriginUrl -Path $legacyDir.FullName
        $repoId = Get-NormalizedRepoId -RepoUrl $repoUrl -FallbackName $legacyDir.Name
        if (@($entries | Where-Object { $_.PrimaryPath -eq $legacyDir.FullName -or $_.RepoId -eq $repoId }).Count -gt 0) {
            continue
        }

        $entries.Add([pscustomobject]@{
                RepoId = $repoId
                RepoUrl = $repoUrl
                PrimaryPath = $legacyDir.FullName
                AllLocalPaths = @($legacyDir.FullName)
                CurrentManifestMirrorClass = "legacy"
                CurrentManifestLicense = ""
                CurrentManifestLicenseStatus = ""
                Source = "legacy"
            })
    }
}

$auditRows = New-Object System.Collections.Generic.List[object]
$excludedRows = New-Object System.Collections.Generic.List[object]

foreach ($entry in $entries) {
    $path = $entry.PrimaryPath
    $exists = Test-Path -LiteralPath $path
    if (-not $exists) {
        $missingReason = if ($entry.CurrentManifestLicenseStatus -eq "historical-alias-unavailable") {
            "historical_alias_not_expected_to_be_mirrored"
        } elseif ($entry.CurrentManifestLicenseStatus -eq "upstream-unavailable") {
            "upstream_unavailable_or_not_publicly_resolvable"
        } else {
            "missing_local_path"
        }
        $excludedRows.Add([pscustomobject]@{
                RepoId = $entry.RepoId
                RepoUrl = $entry.RepoUrl
                Path = $path
                GitRoot = ""
                Reason = $missingReason
            })
        continue
    }

    $gitRoot = Get-GitRoot -Path $path
    if (-not (Test-StandaloneGitRoot -Path $path -GitRoot $gitRoot)) {
        $reason = "not_a_git_root"
        if ($gitRoot) {
            $rootRepoId = Get-NormalizedRepoId -RepoUrl (Get-RemoteOriginUrl -Path $gitRoot) -FallbackName (Split-Path $gitRoot -Leaf)
            if ($rootRepoId -eq $entry.RepoId) {
                $reason = "package_subpath_under_parent_root_authority"
            } else {
                $reason = "non_standalone_git_subpath"
            }
        }
        $excludedRows.Add([pscustomobject]@{
                RepoId = $entry.RepoId
                RepoUrl = $entry.RepoUrl
                Path = $path
                GitRoot = $gitRoot
                Reason = $reason
            })
        continue
    }

    $licenseFiles = Get-RootFilesByPattern -Path $path -Pattern '^(LICENSE|LICEN[CS]E|COPYING)([-_.].+)?(\..+)?$'
    $noticeFiles = Get-RootFilesByPattern -Path $path -Pattern '^NOTICE(\..+)?$'
    $readmeFiles = Get-RootFilesByPattern -Path $path -Pattern '^README([-.].+)?(\..+)?$'

    $licenseFileRows = foreach ($licenseFile in $licenseFiles) {
        $text = Get-Content -LiteralPath $licenseFile.FullName -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
        [pscustomobject]@{
            Name = $licenseFile.Name
            Signal = Get-LicenseSignalFromText -FileName $licenseFile.Name -Text $text
            Text = $text
        }
    }

    $resolvedLicenseSignal = Resolve-RootLicenseSignal -LicenseFileRows $licenseFileRows
    $evidenceTier = ""
    $mitBucket = ""
    $evidencePaths = ""
    $readmeSignal = ""
    $readmeSignalPath = ""
    $metadataSignal = ""
    $metadataSignalPath = ""
    $note = ""
    $copyrightLine = ""

    if ($resolvedLicenseSignal) {
        $evidenceTier = "clear_repo_license_file"
        $evidencePaths = ($licenseFiles.Name -join "; ")
        if ($resolvedLicenseSignal -match 'MIT') {
            $mitBucket = "mit_clear_root_license_file"
            $mitSource = Get-MITTextSource -LicenseFileRows $licenseFileRows
            if ($mitSource) {
                $copyrightLine = Get-CopyrightLine -Text $mitSource.Text
            }
        } else {
            foreach ($licenseFileRow in $licenseFileRows) {
                $copyrightLine = Get-CopyrightLine -Text $licenseFileRow.Text
                if ($copyrightLine) {
                    break
                }
            }
        }
    } else {
        foreach ($readmeFile in $readmeFiles) {
            $readmeText = Get-Content -LiteralPath $readmeFile.FullName -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
            if ($entry.CurrentManifestLicense -match 'MIT' -and $readmeText -match '\bMIT\b') {
                $resolvedLicenseSignal = "MIT"
                $evidenceTier = "readme_only"
                $mitBucket = "mit_readme_only"
                $evidencePaths = $readmeFile.Name
                $readmeSignal = "MIT"
                $readmeSignalPath = $readmeFile.Name
                break
            }
        }

        if (-not $resolvedLicenseSignal) {
            $metadataResult = Get-MetadataSignal -Path $path -ManifestLicense $entry.CurrentManifestLicense
            if ($metadataResult) {
                $resolvedLicenseSignal = $metadataResult.Signal
                $evidenceTier = "metadata_only"
                if ($resolvedLicenseSignal -eq "MIT") {
                    $mitBucket = "mit_metadata_only"
                }
                $evidencePaths = $metadataResult.Path
                $metadataSignal = $metadataResult.Signal
                $metadataSignalPath = $metadataResult.Path
            }
        }
    }

    if (-not $resolvedLicenseSignal) {
        $resolvedLicenseSignal = "no_clear_repo_local_license_signal"
    }

    $repoHead = (git -C $path rev-parse HEAD).Trim()
    if ($entry.CurrentManifestLicense -and $resolvedLicenseSignal -ne "no_clear_repo_local_license_signal") {
        if ($entry.CurrentManifestLicense -notmatch [regex]::Escape($resolvedLicenseSignal)) {
            $note = "Manifest/tracker posture is narrower or more contextual than the root license signal."
        }
    } elseif ($entry.CurrentManifestLicense -and $resolvedLicenseSignal -eq "no_clear_repo_local_license_signal") {
        $note = "Manifest/tracker carries the current legal call, but no standalone repo-local license signal was captured at the mirror root."
    }

    $licenseFileNames = @($licenseFiles | ForEach-Object { $_.Name })
    $noticeFileNames = @($noticeFiles | ForEach-Object { $_.Name })
    $readmeFileNames = @($readmeFiles | ForEach-Object { $_.Name })

    $auditRows.Add([pscustomobject]@{
            repo_id = $entry.RepoId
            repo_url = $entry.RepoUrl
            primary_path = $path
            all_local_paths = ($entry.AllLocalPaths -join "; ")
            current_manifest_mirror_class = $entry.CurrentManifestMirrorClass
            current_manifest_license = $entry.CurrentManifestLicense
            current_manifest_license_status = $entry.CurrentManifestLicenseStatus
            license_file_count = @($licenseFiles).Count
            license_files = ($licenseFileNames -join "; ")
            notice_files = ($noticeFileNames -join "; ")
            readme_files = ($readmeFileNames -join "; ")
            resolved_license_signal = $resolvedLicenseSignal
            evidence_tier = $evidenceTier
            mit_bucket = $mitBucket
            evidence_paths = $evidencePaths
            readme_signal = $readmeSignal
            readme_signal_path = $readmeSignalPath
            metadata_signal = $metadataSignal
            metadata_signal_path = $metadataSignalPath
            copyright_line = $copyrightLine
            repo_head = $repoHead
            note = $note
        })
}

$orderedAuditRows = @($auditRows | Sort-Object repo_id)
$orderedAuditRows | Export-Csv -LiteralPath $csvPath -NoTypeInformation -Encoding UTF8

$mitNoticeBlocks = New-Object System.Collections.Generic.List[string]
foreach ($row in $orderedAuditRows | Where-Object { $_.mit_bucket }) {
    $mitText = ""
    if ($row.mit_bucket -eq "mit_clear_root_license_file") {
        $licenseCandidates = ($row.license_files -split '; ' | Where-Object { $_ })
        foreach ($candidate in $licenseCandidates) {
            $fullPath = Join-Path $row.primary_path $candidate
            $candidateText = Get-Content -LiteralPath $fullPath -Raw -Encoding UTF8 -ErrorAction SilentlyContinue
            if ((Get-LicenseSignalFromText -FileName $candidate -Text $candidateText) -eq "MIT") {
                $mitText = $candidateText
                break
            }
        }
    }

    if (-not $mitText) {
        $mitText = $canonicalMitText
    }

    $mitFilePath = Join-Path $mitTextDir ("{0}.LICENSE.txt" -f (Get-SafeFileStem -RepoId $row.repo_id))
    Write-Utf8NoBomTextFile -Path $mitFilePath -Content ($mitText.TrimEnd() + "`r`n`r`n")

    $block = @(
        "Component: $($row.repo_id)",
        "Source: $($row.repo_url)",
        "Version: $($row.repo_head)",
        "Evidence tier: $($row.evidence_tier)",
        "Evidence path(s): $($row.evidence_paths)"
    )
    if ($row.readme_signal_path) {
        $block += "README evidence: $($row.readme_signal_path)"
    }
    if ($row.metadata_signal_path) {
        $block += "Metadata evidence: $($row.metadata_signal_path)"
    }
    $block += ""
    if ($row.copyright_line) {
        $block += $row.copyright_line
        $block += ""
    }
    $block += "Licensed under the MIT License:"
    $block += ""
    $block += $mitText.TrimEnd()
    $block += ""
    $block += "-----"

    $mitNoticeBlocks.Add(($block -join "`r`n"))
}

Write-Utf8NoBomTextFile -Path $thirdPartyPath -Content (($mitNoticeBlocks -join "`r`n`r`n").TrimEnd() + "`r`n`r`n")

$scannedCount = @($orderedAuditRows).Count
$clearRootCount = @($orderedAuditRows | Where-Object { $_.evidence_tier -eq "clear_repo_license_file" }).Count
$mitClearCount = @($orderedAuditRows | Where-Object { $_.mit_bucket -eq "mit_clear_root_license_file" }).Count
$mitReadmeCount = @($orderedAuditRows | Where-Object { $_.mit_bucket -eq "mit_readme_only" }).Count
$mitMetadataCount = @($orderedAuditRows | Where-Object { $_.mit_bucket -eq "mit_metadata_only" }).Count
$nonMitMetadataCount = @($orderedAuditRows | Where-Object {
        $_.evidence_tier -eq "metadata_only" -and
        -not $_.mit_bucket
    }).Count
$noClearCount = @($orderedAuditRows | Where-Object { $_.resolved_license_signal -eq "no_clear_repo_local_license_signal" }).Count
$noClearWithCanonCount = @($orderedAuditRows | Where-Object {
        $_.resolved_license_signal -eq "no_clear_repo_local_license_signal" -and
        $_.current_manifest_license
    }).Count
$normalizedSubpathCount = @($excludedRows | Where-Object { $_.Reason -eq "package_subpath_under_parent_root_authority" }).Count
$historicalAliasCount = @($excludedRows | Where-Object { $_.Reason -eq "historical_alias_not_expected_to_be_mirrored" }).Count
$remainingExcludedCount = @($excludedRows | Where-Object {
        $_.Reason -ne "package_subpath_under_parent_root_authority" -and
        $_.Reason -ne "historical_alias_not_expected_to_be_mirrored"
    }).Count
$excludedCount = $excludedRows.Count

$markdown = New-Object System.Collections.Generic.List[string]
$markdown.Add("# HyperTwist Repo License Evidence Audit - $Stamp")
$markdown.Add("")
$markdown.Add('Scope: deduped local mirror custody across `C:\Workspaces\HyperTwist\mirrors\{permissive,restrictive}` plus standalone legacy mirrors under `C:\HyperTwist\mirrors`.')
$markdown.Add("")
$markdown.Add("Boundary:")
$markdown.Add("- this is the repo-local legal-evidence pass for mirrored HyperTwist custody, not a rewrite of the broader historical workbook universe")
$markdown.Add("- only standalone git roots count in the live audit")
$markdown.Add("- package-subpath rows that live inside a mirrored monorepo and resolve to the same repo URL are normalized under the parent git-root authority instead of being treated as standalone repo roots")
$markdown.Add("- historical alias rows whose standalone repo surfaces are gone but whose maintained public source surfaces now live elsewhere are kept visible as historical references, not as unresolved mirror-restoration work")
$markdown.Add("- upstream-unavailable rows, unresolved missing mirror paths, and genuinely unrelated non-standalone paths stay visible outside the standalone count instead of being silently discarded")
$markdown.Add('- when later repos are mirrored or their root-license evidence changes, rerun `C:\HyperTwist\scripts\Write-HyperTwistRepoLicenseEvidenceAudit.ps1` in the same pass that updates the legal tracker')
$markdown.Add("")
$markdown.Add("Counts:")
$markdown.Add("- total deduped repos scanned: $scannedCount")
$markdown.Add("- clear repo-local license file or explicit mixed root-license declaration: $clearRootCount")
$markdown.Add("- MIT with clear root license file: $mitClearCount")
$markdown.Add("- MIT from README only, no root license file: $mitReadmeCount")
$markdown.Add("- MIT from repo metadata only, no root license file: $mitMetadataCount")
$markdown.Add("- non-MIT license from repo metadata only, no root license file: $nonMitMetadataCount")
$markdown.Add("- no clear repo-local license signal: $noClearCount")
$markdown.Add("- no-clear bucket where current HyperTwist manifest already carries a legal call: $noClearWithCanonCount")
$markdown.Add("- package-subpath rows normalized under parent root authority: $normalizedSubpathCount")
$markdown.Add("- historical alias rows outside active mirror expectation: $historicalAliasCount")
$markdown.Add("- unresolved upstream-unavailable, missing, or unrelated non-standalone rows outside the live standalone count: $remainingExcludedCount")
$markdown.Add("- total rows outside the standalone live count: $excludedCount")
$markdown.Add("")
$markdown.Add("Artifacts:")
$markdown.Add('- audit CSV: `docs/generated/license_audit/HYPERTWIST_REPO_LICENSE_EVIDENCE_AUDIT_' + $Stamp + '.csv`')
$markdown.Add('- MIT license text capture folder: `docs/generated/license_audit/MIT_LICENSE_TEXTS_' + $Stamp + '/`')
$markdown.Add('- MIT third-party notices draft: `docs/generated/license_audit/THIRD_PARTY_NOTICES_MIT_DRAFT_' + $Stamp + '.txt`')
$markdown.Add("")

$readmeOnlyRows = @($orderedAuditRows | Where-Object { $_.mit_bucket -eq "mit_readme_only" })
$markdown.Add("MIT without root license file - README only:")
if ($readmeOnlyRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $readmeOnlyRows) {
        $markdown.Add("- $($row.repo_id)")
    }
}
$markdown.Add("")

$metadataOnlyRows = @($orderedAuditRows | Where-Object { $_.mit_bucket -eq "mit_metadata_only" })
$markdown.Add("MIT without root license file - metadata only:")
if ($metadataOnlyRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $metadataOnlyRows) {
        $markdown.Add("- $($row.repo_id)")
    }
}
$markdown.Add("")

$nonMitMetadataRows = @($orderedAuditRows | Where-Object {
        $_.evidence_tier -eq "metadata_only" -and
        -not $_.mit_bucket
    })
$markdown.Add("Non-MIT license from repo metadata only, no root license file:")
if ($nonMitMetadataRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $nonMitMetadataRows) {
        $detail = if ($row.metadata_signal_path) {
            "$($row.resolved_license_signal) via ``$($row.metadata_signal_path)``"
        } else {
            $row.resolved_license_signal
        }
        $markdown.Add("- $($row.repo_id) - signal: $detail")
    }
}
$markdown.Add("")

$noClearRows = @($orderedAuditRows | Where-Object { $_.resolved_license_signal -eq "no_clear_repo_local_license_signal" })
$markdown.Add("No clear repo-local license signal:")
if ($noClearRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $noClearRows) {
        if ($row.current_manifest_license) {
            $markdown.Add("- $($row.repo_id) - current manifest call: ``$($row.current_manifest_license)``")
        } else {
            $markdown.Add("- $($row.repo_id)")
        }
    }
}
$markdown.Add("")

$normalizedRows = @($excludedRows | Where-Object { $_.Reason -eq "package_subpath_under_parent_root_authority" } | Sort-Object RepoId, Path)
$markdown.Add("Package-subpath rows normalized under parent root authority:")
if ($normalizedRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $normalizedRows) {
        $markdown.Add("- $($row.Path) -> $($row.GitRoot) (``$($row.Reason)``)")
    }
}
$markdown.Add("")

$historicalAliasRows = @($excludedRows | Where-Object { $_.Reason -eq "historical_alias_not_expected_to_be_mirrored" } | Sort-Object RepoId, Path)
$markdown.Add("Historical alias rows not expected to be mirrored:")
if ($historicalAliasRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $historicalAliasRows) {
        $markdown.Add("- $($row.Path) (``$($row.Reason)``)")
    }
}
$markdown.Add("")

$remainingExcludedRows = @($excludedRows | Where-Object {
        $_.Reason -ne "package_subpath_under_parent_root_authority" -and
        $_.Reason -ne "historical_alias_not_expected_to_be_mirrored"
    } | Sort-Object RepoId, Path)
$markdown.Add("Excluded from the live standalone-git-root count:")
if ($remainingExcludedRows.Count -eq 0) {
    $markdown.Add("- none")
} else {
    foreach ($row in $remainingExcludedRows) {
        if ($row.GitRoot) {
            $markdown.Add("- $($row.Path) -> $($row.GitRoot) (``$($row.Reason)``)")
        } else {
            $markdown.Add("- $($row.Path) (``$($row.Reason)``)")
        }
    }
}
$markdown.Add("")

Write-Utf8NoBomTextFile -Path $markdownPath -Content (($markdown -join "`r`n").TrimEnd() + "`r`n`r`n")

Write-Output "Wrote:"
Write-Output $csvPath
Write-Output $markdownPath
Write-Output $thirdPartyPath
Write-Output $mitTextDir
