[CmdletBinding()]
param(
    [ValidateRange(1, 1000)] [int]$FreeGiBFloor = 360,
    [string]$RuntimeRoot = "D:\NDC_MISSIONCORE\runtime",
    [string]$ContainerImage = "nvcr.io/nvidia/tritonserver:26.06-py3@sha256:58df7489c3f2276f9591d500a012dee03e23d35543ce3c390b4c001e6bf90794",
    [string]$RuntimeName = "perception-e15-media-pyav180-lz445-v1"
)

$ErrorActionPreference = "Stop"
$ProgressPreference = "SilentlyContinue"

function Assert-LastExitCode([string]$Operation) {
    if ($LASTEXITCODE -ne 0) { throw "$Operation failed with exit code $LASTEXITCODE" }
}

function Resolve-DDirectory([string]$Path, [string]$Label) {
    $item = Get-Item -LiteralPath (Resolve-Path -LiteralPath $Path).Path -Force
    $root = [IO.Path]::GetPathRoot($item.FullName).TrimEnd("\")
    if (-not $item.PSIsContainer -or ($item.Attributes -band [IO.FileAttributes]::ReparsePoint) -or $root -ine "D:") {
        throw "$Label must be a real D: directory"
    }
    return $item.FullName
}

function Convert-ToDockerPath([string]$Path) { return $Path.Replace("\", "/") }

function Assert-FreeSpace([string]$Phase) {
    $free = [int64](Get-PSDrive -Name D).Free
    $floor = [int64]$FreeGiBFloor * 1GB
    Write-Host (
        "DISK_GUARD PHASE={0} DRIVE=D FREE_BYTES={1} FREE_GIB={2} FLOOR_GIB={3}" -f
        $Phase, $free, [math]::Round($free / 1GB, 3), $FreeGiBFloor
    )
    if ($free -lt ($floor + 2GB)) {
        throw "D: lacks the guarded LAB E15 media-runtime reserve during $Phase"
    }
    return $free
}

function Get-PayloadDigest([string]$Root) {
    $resolved = Resolve-DDirectory $Root "E15 media runtime"
    $lines = @(
        Get-ChildItem -LiteralPath $resolved -Recurse -File -Force |
            Where-Object { $_.Name -ne "manifest.json" } |
            Sort-Object FullName |
            ForEach-Object {
                $relative = $_.FullName.Substring($resolved.Length).TrimStart("\").Replace("\", "/")
                $hash = (Get-FileHash -LiteralPath $_.FullName -Algorithm SHA256).Hash.ToLowerInvariant()
                "{0}`t{1}`t{2}" -f $relative, $_.Length, $hash
            }
    )
    if ($lines.Count -lt 4) { throw "E15 media runtime payload is incomplete" }
    $bytes = [Text.Encoding]::UTF8.GetBytes(($lines -join "`n") + "`n")
    $hasher = [Security.Cryptography.SHA256]::Create()
    try {
        return ([BitConverter]::ToString($hasher.ComputeHash($bytes))).Replace("-", "").ToLowerInvariant()
    }
    finally { $hasher.Dispose() }
}

function Assert-Runtime([string]$Path) {
    $root = Resolve-DDirectory $Path "E15 media runtime"
    $manifestPath = Join-Path $root "manifest.json"
    if (-not (Test-Path -LiteralPath $manifestPath -PathType Leaf)) {
        throw "E15 media runtime manifest is missing"
    }
    $manifest = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json
    if (
        $manifest.schema_version -ne "missioncore.e15-media-runtime/v1" -or
        $manifest.runtime_name -ne $RuntimeName -or
        $manifest.container_image -ne $ContainerImage -or
        $manifest.packages.av -ne "18.0.0" -or
        $manifest.packages.lz4 -ne "4.4.5" -or
        $manifest.payload_sha256 -ne (Get-PayloadDigest $root)
    ) { throw "E15 media runtime identity changed" }

    $dockerRoot = Convert-ToDockerPath $root
    $verifyCode = "import av,lz4.version;print(av.__version__);print(lz4.version.version)"
    $verifyOutput = @(& docker run --rm --network none --read-only `
        --security-opt "no-new-privileges:true" --cap-drop ALL --pids-limit 64 `
        --tmpfs "/tmp:rw,noexec,nosuid,size=64m" `
        -e "PYTHONPATH=/opt/media" -e "PYTHONDONTWRITEBYTECODE=1" `
        -v ("{0}:/opt/media:ro" -f $dockerRoot) `
        --entrypoint python3 $ContainerImage -c $verifyCode)
    Assert-LastExitCode "E15 media runtime verification"
    if ($verifyOutput.Count -ne 2 -or $verifyOutput[0] -ne "18.0.0" -or $verifyOutput[1] -ne "4.4.5") {
        throw "E15 media runtime package versions changed"
    }
    Write-Host "MEDIA_RUNTIME_OK pyav=18.0.0 lz4=4.4.5"
    return $root
}

$runtime = Resolve-DDirectory $RuntimeRoot "Runtime root"
$derived = Resolve-DDirectory (Join-Path $runtime "derived") "Runtime derived root"
$destination = Join-Path $derived $RuntimeName
$freeBefore = Assert-FreeSpace "media-runtime-preflight"

& docker image inspect $ContainerImage *> $null
Assert-LastExitCode "Pinned container image inspection"

if (Test-Path -LiteralPath $destination) {
    $resolved = Assert-Runtime $destination
    Write-Output "STATE=existing-verified"
    Write-Output ("MEDIA_RUNTIME_ROOT={0}" -f $resolved)
    Write-Output ("DISK_FREE_BYTES_BEFORE={0}" -f $freeBefore)
    Write-Output ("DISK_FREE_BYTES_AFTER={0}" -f ([int64](Get-PSDrive -Name D).Free))
    return
}

$token = [Guid]::NewGuid().ToString("N")
$staging = Join-Path $derived (".{0}-{1}.tmp" -f $RuntimeName, $token)
$null = New-Item -ItemType Directory -Path $staging
$completed = $false
try {
    $dockerStaging = Convert-ToDockerPath $staging
    Write-Output "PHASE=media-runtime-install-start"
    & docker run --rm --network bridge --read-only `
        --security-opt "no-new-privileges:true" --cap-drop ALL --pids-limit 128 `
        --tmpfs "/tmp:rw,nosuid,size=1g" `
        -e "PIP_DISABLE_PIP_VERSION_CHECK=1" -e "PYTHONDONTWRITEBYTECODE=1" `
        -v ("{0}:/target:rw" -f $dockerStaging) `
        --entrypoint python3 $ContainerImage -m pip install `
        --no-cache-dir --only-binary ":all:" --target /target `
        "av==18.0.0" "lz4==4.4.5"
    Assert-LastExitCode "E15 media runtime installation"

    $payloadSha256 = Get-PayloadDigest $staging
    $manifest = [ordered]@{
        schema_version = "missioncore.e15-media-runtime/v1"
        runtime_name = $RuntimeName
        created_at_utc = [DateTime]::UtcNow.ToString("yyyy-MM-ddTHH:mm:ss.fffZ")
        container_image = $ContainerImage
        packages = [ordered]@{ av = "18.0.0"; lz4 = "4.4.5" }
        payload_sha256 = $payloadSha256
        storage_scope = "D-only-immutable-runtime"
    }
    $manifest | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath (Join-Path $staging "manifest.json") -Encoding utf8
    $null = Assert-Runtime $staging
    Move-Item -LiteralPath $staging -Destination $destination
    $completed = $true
    $resolved = Assert-Runtime $destination
    $freeAfter = Assert-FreeSpace "media-runtime-published"
    Write-Output "STATE=created-verified"
    Write-Output ("MEDIA_RUNTIME_ROOT={0}" -f $resolved)
    Write-Output ("PAYLOAD_SHA256={0}" -f $payloadSha256)
    Write-Output ("DISK_FREE_BYTES_BEFORE={0}" -f $freeBefore)
    Write-Output ("DISK_FREE_BYTES_AFTER={0}" -f $freeAfter)
}
finally {
    if (-not $completed -and (Test-Path -LiteralPath $staging)) {
        Remove-Item -LiteralPath $staging -Recurse -Force
    }
}
