[CmdletBinding()]
param(
  [string]$SmartCutCli = "build\ucrt64-ffmpeg\smartcut-cli.exe",
  [string]$Hdr10PlusTool = "build\tools\hdr10plus_tool-1.7.0\hdr10plus_tool.exe",
  [string]$SourceMetadata = "build\tools\hdr10plus_tool-src\assets\hevc_tests\regular_metadata.json",
  [string]$Ffmpeg = "C:\ffmpeg_latest\ffmpeg.exe",
  [string]$OutputMkv = "build\m2-hdr10plus-variation.mkv",
  [string]$OutputReport = "build\m2-hdr10plus-variation.json"
)

$projectRoot = Split-Path -Parent $PSScriptRoot
function Resolve-ProjectPath([string]$Path) {
  if ([System.IO.Path]::IsPathRooted($Path)) { return $Path }
  return [System.IO.Path]::GetFullPath((Join-Path $projectRoot $Path))
}
function Require-File([string]$Path, [string]$Description) {
  if (-not (Test-Path -LiteralPath $Path -PathType Leaf)) { throw "Missing $Description`: $Path" }
}
function Run-External([string]$File, [string[]]$Arguments) {
  & $File @Arguments
  if ($LASTEXITCODE -ne 0) { throw "Command failed ($LASTEXITCODE): $File $($Arguments -join ' ')" }
}
function Get-JsonHash($Value) {
  $json = $Value | ConvertTo-Json -Depth 30 -Compress
  $bytes = [System.Text.Encoding]::UTF8.GetBytes($json)
  $sha256 = [System.Security.Cryptography.SHA256]::Create()
  try { $hash = $sha256.ComputeHash($bytes) } finally { $sha256.Dispose() }
  return ([System.BitConverter]::ToString($hash) -replace '-', '').ToLowerInvariant()
}

$cli = Resolve-ProjectPath $SmartCutCli
$tool = Resolve-ProjectPath $Hdr10PlusTool
$metadata = Resolve-ProjectPath $SourceMetadata
$ffmpeg = Resolve-ProjectPath $Ffmpeg
$mkv = Resolve-ProjectPath $OutputMkv
$reportPath = Resolve-ProjectPath $OutputReport
$baseMkv = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-base.mkv"
$baseHevc = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-base.hevc"
$cleanHevc = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-clean.hevc"
$injectedHevc = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-injected.hevc"
$editJson = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-edit.json"
$editedMetadata = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-metadata.json"
$extractedMetadata = Join-Path (Split-Path $mkv) "m2-hdr10plus-variation-extracted.json"

Require-File $cli "FFmpeg-enabled SmartCut CLI"
Require-File $tool "hdr10plus_tool"
Require-File $metadata "HDR10+ source metadata"
Require-File $ffmpeg "FFmpeg executable"
New-Item -ItemType Directory -Path (Split-Path $mkv) -Force | Out-Null
Set-Content -LiteralPath $editJson -Value '{"remove":["5-258"]}' -NoNewline

$savedPath = $env:Path
$env:Path = (Join-Path $projectRoot "artifacts\m1\bin") + ";C:\msys642\ucrt64\bin;" + $env:Path
try {
  & $cli metadata-lab --generate-mkv $baseMkv
  if ($LASTEXITCODE -ne 0) { throw "Base MKV generation failed" }
  Run-External $ffmpeg @("-y", "-i", $baseMkv, "-map", "0:v:0", "-c", "copy", "-bsf:v", "hevc_mp4toannexb", $baseHevc)
  Run-External $tool @("remove", "-i", $baseHevc, "-o", $cleanHevc)
  Run-External $tool @("editor", "-i", $metadata, "-j", $editJson, "-o", $editedMetadata)
  Run-External $tool @("inject", "-i", $cleanHevc, "-j", $editedMetadata, "-o", $injectedHevc)
  Run-External $ffmpeg @("-y", "-f", "hevc", "-i", $injectedHevc, "-c", "copy", "-f", "matroska", $mkv)
  Run-External $tool @("extract", "-i", $mkv, "-o", $extractedMetadata)

  $inventoryJson = & $cli metadata-lab --container --input $mkv --max-frames 5
  if ($LASTEXITCODE -ne 0) { throw "Container inventory failed" }
  $inventory = $inventoryJson | ConvertFrom-Json
  $sourceMetadataObject = Get-Content -LiteralPath $editedMetadata -Raw | ConvertFrom-Json
  $outputMetadataObject = Get-Content -LiteralPath $extractedMetadata -Raw | ConvertFrom-Json
  $sourceFrames = @($sourceMetadataObject.SceneInfo)
  $outputFrames = @($outputMetadataObject.SceneInfo)
  $frameComparison = @()
  $comparisonCount = [Math]::Min($sourceFrames.Count, $outputFrames.Count)
  for ($frame = 0; $frame -lt $comparisonCount; $frame++) {
    $sourceHash = Get-JsonHash $sourceFrames[$frame]
    $outputHash = Get-JsonHash $outputFrames[$frame]
    $frameComparison += [ordered]@{
      frame = $frame
      source_sha256 = $sourceHash
      output_sha256 = $outputHash
      equal = ($sourceHash -eq $outputHash)
    }
  }
  $comparisonComplete = ($sourceFrames.Count -eq 5 -and $outputFrames.Count -eq 5 -and $frameComparison.Count -eq 5 -and @($frameComparison | Where-Object { -not $_.equal }).Count -eq 0)
  $gate = [ordered]@{
    schema = "metadata-lab-m2-hdr10plus-variation-v1"
    output = $mkv
    decoded_frames = $inventory.decoded_frames
    decoded_is_10bit = $inventory.decoded_is_10bit
    packet_sei_nals = $inventory.packet_sei_nals
    packet_sei_variants = $inventory.packet_sei_variants
    hdr10plus_sei_bytes = $inventory.hdr10plus_sei_bytes
    source_metadata_frames = $sourceFrames.Count
    output_metadata_frames = $outputFrames.Count
    metadata_frame_comparison_complete = $comparisonComplete
    metadata_frame_comparison = $frameComparison
    passed = ($inventory.decoded_frames -ge 5 -and $inventory.decoded_is_10bit -and $inventory.packet_sei_nals -ge 5 -and $inventory.packet_sei_variants -ge 2 -and $inventory.hdr10plus_sei_bytes -gt 0 -and $comparisonComplete)
    container_report = $inventory
  }
  $gate | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $reportPath -Encoding utf8
  Get-Content -LiteralPath $reportPath
  if (-not $gate.passed) { exit 5 }
}
finally { $env:Path = $savedPath }
