# build_resource_dll.ps1 -- builds a pure resource DLL from a folder tree.
#
#   powershell -File tools\resource_dll\build_resource_dll.ps1 -Source <dir> -Out <dll> [-Machine X64|X86]
#
# Layout of -Source (first-level folder = resource TYPE, the rest = the NAME):
#   resources\
#     png\sample.png          -> type PNG  name SAMPLE
#     png\ribbon\copy.png     -> type PNG  name RIBBON/COPY      (multi-level!)
#     svg\ribbon\copy.svg     -> type SVG  name RIBBON/COPY      (same name, other type)
#     ico\app.ico             -> standard ICON group, name APP
#     gif\anim\loader.gif     -> type GIF  name ANIM/LOADER
#
# Consumed by the PBToolboxAI _file route:
#   pack.dll:SAMPLE               (flat: fixed probe order icon/PNG/JPG/GIF/BMP/SVG/RCDATA)
#   pack.dll:PNG/RIBBON/COPY      (explicit type, any depth after it)
#   pack.dll:SVG/RIBBON/COPY
#   pack.dll:ICON/APP
#
# Names and types are stored UPPERCASE (the route uppercases before lookup).
param(
    [Parameter(Mandatory = $true)][string]$Source,
    [Parameter(Mandatory = $true)][string]$Out,
    [ValidateSet("X64", "X86")][string]$Machine = "X64"
)
$ErrorActionPreference = "Stop"

function Find-Tool([string]$pattern) {
    $hit = Get-ChildItem $pattern -ErrorAction SilentlyContinue | Sort-Object FullName -Descending | Select-Object -First 1
    if ($null -eq $hit) { throw "tool not found: $pattern" }
    return $hit.FullName
}
$hostDir = if ($Machine -eq "X64") { "x64" } else { "x86" }
$rc = Find-Tool "C:\Program Files (x86)\Windows Kits\10\bin\10.*\x64\rc.exe"
$link = Find-Tool "C:\Program Files (x86)\Microsoft Visual Studio\*\*\VC\Tools\MSVC\*\bin\Hostx64\$hostDir\link.exe"

$src = (Resolve-Path $Source).Path
if (-not [System.IO.Path]::IsPathRooted($Out)) { $Out = Join-Path (Get-Location) $Out }
$files = Get-ChildItem $src -Recurse -File
if ($files.Count -eq 0) { throw "no files under $src" }

$rcLines = New-Object System.Collections.Generic.List[string]
foreach ($f in $files) {
    $rel = $f.FullName.Substring($src.Length).TrimStart("\")
    $parts = $rel -split "\\"
    if ($parts.Count -lt 2) { continue }   # root files = tooling (empty.dll, README...), not resources
    if ($rel -match "\s") { Write-Warning "skipped (spaces unsupported in resource names): $rel"; continue }
    $type = $parts[0].ToUpperInvariant()
    $nameParts = $parts[1..($parts.Count - 1)]
    $nameParts[-1] = [System.IO.Path]::GetFileNameWithoutExtension($nameParts[-1])
    $name = ($nameParts -join "/").ToUpperInvariant()
    $file = $f.FullName -replace "\\", "\\"
    if ($f.Extension -ieq ".ico") {
        # standard icon group (served rebuilt as .ico; also reachable as ICON/<name>)
        $rcLines.Add("$name ICON `"$file`"")
    } else {
        $rcLines.Add("$name $type `"$file`"")
    }
}
if ($rcLines.Count -eq 0) { throw "nothing to embed" }

$tmp = Join-Path $env:TEMP ("pbt_resdll_" + [guid]::NewGuid().ToString("n"))
New-Item -ItemType Directory -Path $tmp | Out-Null
try {
    $rcFile = Join-Path $tmp "pack.rc"
    $resFile = Join-Path $tmp "pack.res"
    Set-Content -Path $rcFile -Value ($rcLines -join "`r`n") -Encoding ascii
    & $rc /nologo /fo $resFile $rcFile
    if ($LASTEXITCODE -ne 0) { throw "rc.exe failed ($LASTEXITCODE)" }
    # /Brepro : REPRODUCTIBLE. Sans lui, link.exe tamponne l'heure de construction
    # dans l'en-tete PE, et la DLL ressortait DIFFERENTE a chaque appel alors que
    # ses ressources etaient identiques au bit pres -- six octets, l'horodatage et
    # sa somme de controle. Elle est versionnee : chaque empaquetage de la demo la
    # faisait donc reapparaitre modifiee dans git status, pour rien. Avec ce
    # drapeau, memes images = meme fichier.
    & $link /NOLOGO /DLL /NOENTRY /Brepro /MACHINE:$Machine $resFile ("/OUT:" + $Out)
    if ($LASTEXITCODE -ne 0) { throw "link.exe failed ($LASTEXITCODE)" }
    Write-Host ("OK : {0} resources -> {1}" -f $rcLines.Count, $Out)
} finally {
    Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
}
