# Validates legal/release-readiness files that must be present before shipping.
param(
    [switch]$Release,
    [string]$Root = (Resolve-Path "$PSScriptRoot\..").Path
)

$ErrorActionPreference = "Stop"

$ExpectedProductName = "Slipstream DRC"
$ExpectedPublisher = "Nanometer Advisors, LLC"
$ExpectedIdentifier = "com.nanometeradvisors.slipstreamdrc"
$ExpectedUpdaterEndpoint = "https://updates.nanometeradvisors.com/slipstream-drc/latest.json"
$ExpectedFfmpegArchiveSha256 = "DB580001CAA24AC104C8CB856CD113A87B0A443F7BDF47D8C12B1D740584A2EC"
$ExpectedFfmpegSha256 = "1326DDE4C84FF1F96FE6B8916C5BED29E163E9B5DCCF995F6F3DB069D143EC5E"
$ExpectedFfprobeSha256 = "B49CCC7C6547B141AD5A2F6EC69CC04323D7133D7704D70B331B904C63EECB07"
$ExpectedFfmpegSourceCommit = "38b88335f9"
$ExpectedFfmpegSourceSha256 = "2AE7E42343CFFFB811D15CFE98B6D005F082595FCDF034D30A4FF90CFED9F9C6"

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

    $Stream = [System.IO.File]::OpenRead($Path)
    try {
        $Hasher = [System.Security.Cryptography.SHA256]::Create()
        try {
            return ([System.BitConverter]::ToString($Hasher.ComputeHash($Stream))).Replace("-", "")
        } finally {
            $Hasher.Dispose()
        }
    } finally {
        $Stream.Dispose()
    }
}

$RequiredFiles = @(
    "LICENSE",
    "LICENSE.md",
    "EULA.md",
    "PRIVACY.md",
    "THIRD_PARTY_NOTICES.md",
    "licenses\APP-LICENSE.txt",
    "licenses\FFMPEG-GYAN-README.txt",
    "licenses\GPL-3.0.txt",
    "licenses\FFMPEG-SOURCE.md",
    "licenses\LEGACY-MIT-v0.3.0.txt",
    "licenses\npm-dependencies.txt",
    "licenses\rust-dependencies.txt",
    "public\legal\app-license.txt",
    "public\legal\third-party-notices.txt",
    "public\legal\ffmpeg-source.txt",
    "public\legal\privacy.txt"
)

foreach ($RelativePath in $RequiredFiles) {
    $FullPath = Join-Path $Root $RelativePath
    if (-not (Test-Path $FullPath)) {
        throw "Missing required legal file: $RelativePath"
    }
}

$Notice = Get-Content (Join-Path $Root "THIRD_PARTY_NOTICES.md") -Raw
$FfmpegSource = Get-Content (Join-Path $Root "licenses\FFMPEG-SOURCE.md") -Raw
$PublicFfmpeg = Get-Content (Join-Path $Root "public\legal\ffmpeg-source.txt") -Raw

$FfmpegExe = Join-Path $Root "src-tauri\binaries\ffmpeg-x86_64-pc-windows-msvc.exe"
if (-not (Test-Path $FfmpegExe)) {
    throw "Missing FFmpeg sidecar. Run npm run fetch-ffmpeg."
}

$FfmpegVersionOutput = & $FfmpegExe -version
$FfmpegFirstLine = [string]($FfmpegVersionOutput | Select-Object -First 1)
$ExpectedVersion = "8.1.2-essentials_build-www.gyan.dev"

if (-not $FfmpegFirstLine.Contains($ExpectedVersion)) {
    throw "FFmpeg sidecar version mismatch. Expected '$ExpectedVersion' in '$FfmpegFirstLine'."
}

function Assert-Sha256 {
    param(
        [string]$Path,
        [string]$Expected
    )

    $Actual = (Get-FileSha256 -Path $Path).ToUpperInvariant()
    if ($Actual -ne $Expected.ToUpperInvariant()) {
        throw "SHA256 mismatch for $Path. Expected $Expected, got $Actual."
    }
}

Assert-Sha256 -Path $FfmpegExe -Expected $ExpectedFfmpegSha256
Assert-Sha256 -Path (Join-Path $Root "src-tauri\binaries\ffprobe-x86_64-pc-windows-msvc.exe") -Expected $ExpectedFfprobeSha256

$GyanReadme = Get-Content (Join-Path $Root "licenses\FFMPEG-GYAN-README.txt") -Raw
if (-not $GyanReadme.Contains("Version: $ExpectedVersion")) {
    throw "Gyan FFmpeg README does not identify $ExpectedVersion."
}
if (-not $GyanReadme.Contains("Source Code: https://github.com/FFmpeg/FFmpeg/commit/$ExpectedFfmpegSourceCommit")) {
    throw "Gyan FFmpeg README does not identify source commit $ExpectedFfmpegSourceCommit."
}

foreach ($Text in @($Notice, $FfmpegSource, $PublicFfmpeg)) {
    if (-not $Text.Contains($ExpectedVersion)) {
        throw "FFmpeg notice files must mention $ExpectedVersion."
    }
    if (-not $Text.Contains("--enable-gpl") -or -not $Text.Contains("--enable-version3")) {
        throw "FFmpeg notice files must include the GPL/version3 configure flags."
    }
    if (-not $Text.Contains($ExpectedFfmpegSourceCommit)) {
        throw "FFmpeg notice files must mention source commit $ExpectedFfmpegSourceCommit."
    }
    if (-not $Text.Contains($ExpectedFfmpegSourceSha256)) {
        throw "FFmpeg notice files must mention source archive SHA256 $ExpectedFfmpegSourceSha256."
    }
    if (-not $Text.Contains($ExpectedFfmpegArchiveSha256)) {
        throw "FFmpeg notice files must mention binary archive SHA256 $ExpectedFfmpegArchiveSha256."
    }
}

$GplText = Get-Content (Join-Path $Root "licenses\GPL-3.0.txt") -Raw
if (-not $GplText.Contains("GNU GENERAL PUBLIC LICENSE") -or -not $GplText.Contains("Version 3")) {
    throw "licenses/GPL-3.0.txt does not look like GPLv3 text."
}

$PackageJson = Get-Content (Join-Path $Root "package.json") -Raw | ConvertFrom-Json
if ($PackageJson.private -ne $true) {
    throw "package.json must be private for commercial distribution."
}
if ($PackageJson.license -ne "UNLICENSED") {
    throw "package.json license must be UNLICENSED for commercial distribution."
}
if ($PackageJson.author -ne $ExpectedPublisher) {
    throw "package.json author must be $ExpectedPublisher."
}

$CargoToml = Get-Content (Join-Path $Root "src-tauri\Cargo.toml") -Raw
if (-not $CargoToml.Contains("publish = false")) {
    throw "src-tauri/Cargo.toml must set publish = false."
}
if (-not $CargoToml.Contains("authors = [""$ExpectedPublisher""]")) {
    throw "src-tauri/Cargo.toml authors must include $ExpectedPublisher."
}

$TauriConfig = Get-Content (Join-Path $Root "src-tauri\tauri.conf.json") -Raw | ConvertFrom-Json
if ($TauriConfig.productName -ne $ExpectedProductName) {
    throw "Tauri productName must be $ExpectedProductName."
}
if ($TauriConfig.identifier -ne $ExpectedIdentifier) {
    throw "Tauri identifier must be $ExpectedIdentifier."
}

$UpdaterEndpoints = @($TauriConfig.plugins.updater.endpoints)
if ($UpdaterEndpoints.Count -lt 1) {
    throw "Tauri updater endpoints must be configured."
}
if ($UpdaterEndpoints -notcontains $ExpectedUpdaterEndpoint) {
    throw "Tauri updater endpoint must be $ExpectedUpdaterEndpoint."
}
foreach ($Endpoint in $UpdaterEndpoints) {
    if ($Endpoint -match "github\.com") {
        throw "Release blocker: updater endpoint must not use github.com ($Endpoint)."
    }
}

$LicenseText = Get-Content (Join-Path $Root "LICENSE.md") -Raw
$EulaText = Get-Content (Join-Path $Root "EULA.md") -Raw
foreach ($Content in @($LicenseText, $EulaText)) {
    if (-not $Content.Contains($ExpectedPublisher)) {
        throw "App license files must name $ExpectedPublisher."
    }
    if (-not $Content.Contains($ExpectedProductName)) {
        throw "App license files must name $ExpectedProductName."
    }
}

$CustomerFacingLegal = @(
    "LICENSE",
    "LICENSE.md",
    "EULA.md",
    "PRIVACY.md",
    "licenses\APP-LICENSE.txt",
    "public\legal\app-license.txt",
    "public\legal\privacy.txt"
)

$ForbiddenCustomerPhrases = @(
    "draft",
    "attorney approval",
    "Release Blocker",
    "Release blocker"
)

foreach ($RelativePath in $CustomerFacingLegal) {
    $Content = Get-Content (Join-Path $Root $RelativePath) -Raw
    foreach ($Phrase in $ForbiddenCustomerPhrases) {
        if ($Content -match [regex]::Escape($Phrase)) {
            throw "Customer-facing legal file $RelativePath still contains '$Phrase'."
        }
    }
}

if ($Release) {
    $LegalEntityPlaceholder = "<" + "LEGAL_ENTITY_NAME" + ">"
    $AllTextFiles = Get-ChildItem -Path $Root -Recurse -File |
        Where-Object {
            $_.FullName -notmatch "\\.git\\" -and
            $_.FullName -notmatch "\\node_modules\\" -and
            $_.FullName -notmatch "\\target\\" -and
            $_.Extension -in @(".md", ".txt", ".json", ".toml", ".yml", ".yaml", ".tsx", ".ts", ".rs", ".ps1")
        }

    foreach ($File in $AllTextFiles) {
        $Content = Get-Content $File.FullName -Raw
        if ($Content.Contains($LegalEntityPlaceholder)) {
            $Relative = Resolve-Path -Path $File.FullName -Relative
            throw "Release blocker: replace $LegalEntityPlaceholder in $Relative."
        }
    }

    if (-not $env:CI_SIGNING_REQUIRED) {
        throw "Release blocker: CI_SIGNING_REQUIRED must be set for paid releases."
    }
}

Write-Host "Legal readiness checks passed."
