[CmdletBinding()]
param(
  [string]$RepositoryRoot,
  [string]$SourceCache,
  [string]$BuildRoot,
  [string]$InstallRoot
)

$ErrorActionPreference = 'Stop'
$scriptRoot = Split-Path -Parent $MyInvocation.MyCommand.Path
if ([string]::IsNullOrWhiteSpace($RepositoryRoot)) { $RepositoryRoot = (Resolve-Path (Join-Path $scriptRoot '..\..')).Path }
. (Join-Path $RepositoryRoot 'scripts/hash-utils.ps1')
if ([string]::IsNullOrWhiteSpace($SourceCache)) { $SourceCache = Join-Path $RepositoryRoot 'dependencies\sources' }
if ([string]::IsNullOrWhiteSpace($BuildRoot)) { $BuildRoot = Join-Path $RepositoryRoot 'build\dependencies-m1' }
if ([string]::IsNullOrWhiteSpace($InstallRoot)) { $InstallRoot = Join-Path $RepositoryRoot 'artifacts\m1' }

$manifestPath = Join-Path $RepositoryRoot 'dependencies\manifests\m1-dependencies.json'
$configurePath = Join-Path $RepositoryRoot 'dependencies\manifests\ffmpeg-windows-x64.configure.txt'
$lock = Get-Content -LiteralPath $manifestPath -Raw | ConvertFrom-Json

& (Join-Path $scriptRoot 'verify-lock.ps1') -Manifest $manifestPath

$requiredTools = @('bash', 'make', 'nasm', 'perl')
$windowsTar = Join-Path $env:SystemRoot 'System32\\tar.exe'
if (-not (Test-Path -LiteralPath $windowsTar)) { throw 'Windows tar.exe not found' }
$missingTools = @($requiredTools | Where-Object { $null -eq (Get-Command $_ -ErrorAction SilentlyContinue) })
if ($missingTools.Count -gt 0) {
  throw "M1 build prerequisites missing: $($missingTools -join ', '). Install a supported MSYS2 toolchain with these tools, then rerun this script from the x64 Visual Studio environment."
}

New-Item -ItemType Directory -Force -Path $BuildRoot, $InstallRoot | Out-Null
$resolved = [System.Collections.Generic.List[object]]::new()
foreach ($dependency in $lock.dependencies) {
  $archiveName = if ($dependency.archiveFile) { [string]$dependency.archiveFile } else { "{0}.archive" -f $dependency.name }
  $archive = Join-Path $SourceCache $archiveName
  if (-not (Test-Path -LiteralPath $archive)) { throw "Missing source archive: $archive" }
  $actualHash = (Get-SmartCutSha256 -LiteralPath $archive).ToLowerInvariant()
  if ($actualHash -ne $dependency.archiveSha256.ToLowerInvariant()) {
    throw "Archive hash mismatch for $($dependency.name): expected $($dependency.archiveSha256), got $actualHash"
  }
  $sourceDir = Join-Path $BuildRoot ("source\{0}" -f $dependency.name)
  if (Test-Path -LiteralPath $sourceDir) { Remove-Item -LiteralPath $sourceDir -Recurse -Force }
  New-Item -ItemType Directory -Force -Path $sourceDir | Out-Null
  $stripComponents = if ($null -ne $dependency.stripComponents) { [int]$dependency.stripComponents } else { 1 }
  if ($stripComponents -gt 0) {
    & $windowsTar -xf $archive -C $sourceDir "--strip-components=$stripComponents"
  } else {
    & $windowsTar -xf $archive -C $sourceDir
  }
  if ($LASTEXITCODE -ne 0) { throw "Archive extraction failed for $($dependency.name)" }
  $resolved.Add([pscustomobject]@{name=$dependency.name;version=$dependency.version;revision=$dependency.revision;archiveSha256=$actualHash;sourceDirectory=$sourceDir})
}

Get-Content -LiteralPath $configurePath | Set-Content -LiteralPath (Join-Path $BuildRoot 'ffmpeg-configure.txt')
[pscustomobject]@{
  schemaVersion = 1
  target = 'windows-x64'
  generatedUtc = (Get-Date).ToUniversalTime().ToString('o')
  dependencies = @($resolved)
} | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath (Join-Path $BuildRoot 'resolved-dependencies.json') -Encoding utf8

Write-Output "Verified and extracted $($resolved.Count) dependencies to $BuildRoot"
Write-Output "Next build inputs are recorded in $BuildRoot\ffmpeg-configure.txt"
