param(
  [string]$RepositoryRoot = (Split-Path -Parent $PSScriptRoot),
  [string]$DefaultPackageName = "audio_path_tone_tester-0.1.0-ks-wavert-playback-source-20260621",
  [string]$AsioPackageName = "audio_path_tone_tester-0.1.0-ks-wavert-playback-gplv3-asio-source-20260621"
)

$ErrorActionPreference = "Stop"

function Resolve-ExistingOrParent {
  param([string]$Path)
  if (Test-Path -LiteralPath $Path) {
    return (Resolve-Path -LiteralPath $Path).Path
  }
  $parent = Split-Path -Parent $Path
  $name = Split-Path -Leaf $Path
  return (Join-Path (Resolve-Path -LiteralPath $parent).Path $name)
}

function Assert-UnderRoot {
  param(
    [string]$Path,
    [string]$Root
  )
  $resolvedPath = Resolve-ExistingOrParent -Path $Path
  $resolvedRoot = (Resolve-Path -LiteralPath $Root).Path
  if (!$resolvedPath.StartsWith($resolvedRoot, [System.StringComparison]::OrdinalIgnoreCase)) {
    throw "Refusing to operate outside review root: $resolvedPath"
  }
}

function Reset-Path {
  param(
    [string]$Path,
    [string]$Root
  )
  Assert-UnderRoot -Path $Path -Root $Root
  if (Test-Path -LiteralPath $Path) {
    Remove-Item -LiteralPath $Path -Recurse -Force
  }
}

function Copy-IfExists {
  param(
    [string]$Source,
    [string]$Destination
  )
  if (Test-Path -LiteralPath $Source) {
    Copy-Item -LiteralPath $Source -Destination $Destination -Force
  }
}

function Copy-Tree {
  param(
    [string]$Source,
    [string]$Destination
  )
  Copy-Item -LiteralPath $Source -Destination $Destination -Recurse -Force
}

function Copy-DearImguiAllowlist {
  param([string]$PackageRoot)

  $imguiRoot = Join-Path $RepositoryRoot "third_party\imgui"
  $packageImguiRoot = Join-Path $PackageRoot "third_party\imgui"
  New-Item -ItemType Directory -Force -Path $packageImguiRoot | Out-Null
  New-Item -ItemType Directory -Force -Path (Join-Path $packageImguiRoot "backends") | Out-Null

  $files = @(
    "LICENSE.txt",
    "imconfig.h",
    "imgui.cpp",
    "imgui.h",
    "imgui_draw.cpp",
    "imgui_internal.h",
    "imgui_tables.cpp",
    "imgui_widgets.cpp",
    "imstb_rectpack.h",
    "imstb_textedit.h",
    "imstb_truetype.h",
    "backends\imgui_impl_dx11.cpp",
    "backends\imgui_impl_dx11.h",
    "backends\imgui_impl_win32.cpp",
    "backends\imgui_impl_win32.h"
  )

  foreach ($file in $files) {
    $source = Join-Path $imguiRoot $file
    $destination = Join-Path $packageImguiRoot $file
    New-Item -ItemType Directory -Force -Path (Split-Path -Parent $destination) | Out-Null
    Copy-Item -LiteralPath $source -Destination $destination -Force
  }
}

function Write-CommonReadme {
  param(
    [string]$PackageRoot,
    [bool]$AsioEnabled
  )

  $asioText = if ($AsioEnabled) {
    "This package includes the Steinberg ASIO SDK source tree for the owner-approved GPLv3 ASIO-enabled review path. It does not include vendor ASIO drivers or use ASIO logo artwork as product branding."
  } else {
    "This package is the ASIO-disabled source review package. It intentionally excludes the Steinberg ASIO SDK tree and ASIO logo artwork."
  }

  @"
# Source Review Package

Generated for external review of Audio Path Tone Tester.

$asioText

The package includes project source, tests, CMake metadata, docs, and only the
Dear ImGui source files used by this application. Generated build outputs,
release packages, bundled fonts, and prebuilt binaries are excluded from the
default review package.
"@ | Set-Content -LiteralPath (Join-Path $PackageRoot "SOURCE_REVIEW_README.md") -Encoding UTF8
}

function New-ReviewPackage {
  param(
    [string]$Name,
    [bool]$IncludeAsioSdk,
    [string]$ReviewRoot
  )

  $packageRoot = Join-Path $ReviewRoot $Name
  $zipPath = "$packageRoot.zip"
  Reset-Path -Path $packageRoot -Root $ReviewRoot
  Reset-Path -Path $zipPath -Root $ReviewRoot
  New-Item -ItemType Directory -Force -Path $packageRoot | Out-Null

  foreach ($file in @("AGENTS.md", "CMakeLists.txt", "CMakePresets.json", ".gitignore", ".rgignore", "README.md")) {
    Copy-IfExists -Source (Join-Path $RepositoryRoot $file) -Destination $packageRoot
  }

  foreach ($dir in @("src", "tests", "cmake", "docs")) {
    Copy-Tree -Source (Join-Path $RepositoryRoot $dir) -Destination $packageRoot
  }

  Copy-DearImguiAllowlist -PackageRoot $packageRoot

  if ($IncludeAsioSdk) {
    Copy-Tree -Source (Join-Path $RepositoryRoot "ASIO-SDK_2.3.4_2025-10-15") -Destination $packageRoot
    @"
# Source Availability

This is the owner-approved GPLv3 ASIO-enabled corresponding-source review
package for Audio Path Tone Tester.

It includes the project source tree, selected third-party source files, and the
Steinberg ASIO SDK package used by the local ASIO-enabled build. Vendor ASIO
drivers and ASIO logo artwork are not product branding and are not bundled as
runtime drivers.
"@ | Set-Content -LiteralPath (Join-Path $packageRoot "SOURCE_AVAILABILITY.txt") -Encoding UTF8
  }

  Write-CommonReadme -PackageRoot $packageRoot -AsioEnabled:$IncludeAsioSdk
  Compress-Archive -LiteralPath $packageRoot -DestinationPath $zipPath -Force
  $hash = (Get-FileHash -LiteralPath $zipPath -Algorithm SHA256).Hash
  return [pscustomobject]@{
    Name = $Name
    Directory = $packageRoot
    Zip = $zipPath
    Sha256 = $hash
  }
}

$RepositoryRoot = (Resolve-Path -LiteralPath $RepositoryRoot).Path
$reviewRoot = Join-Path $RepositoryRoot "external_review_source"
New-Item -ItemType Directory -Force -Path $reviewRoot | Out-Null

$defaultPackage = New-ReviewPackage -Name $DefaultPackageName -IncludeAsioSdk:$false -ReviewRoot $reviewRoot
$asioPackage = New-ReviewPackage -Name $AsioPackageName -IncludeAsioSdk:$true -ReviewRoot $reviewRoot

$manifest = Join-Path $reviewRoot "CURRENT_REVIEW_PACKAGES.txt"
@"
Audio Path Tone Tester current source review packages
Generated: $(Get-Date -Format "yyyy-MM-ddTHH:mm:ssK")

Default ASIO-disabled review source:
Directory: $($defaultPackage.Directory)
Zip: $($defaultPackage.Zip)
SHA-256: $($defaultPackage.Sha256)

GPLv3 ASIO-enabled corresponding source:
Directory: $($asioPackage.Directory)
Zip: $($asioPackage.Zip)
SHA-256: $($asioPackage.Sha256)
"@ | Set-Content -LiteralPath $manifest -Encoding UTF8

Get-Content -LiteralPath $manifest
