#Requires -Version 5.1

<#

.SYNOPSIS  Apply SilverMetal Windows branding (4 layers), offline (WIM) or online.

.DESCRIPTION

    Offline: reg-load the mounted image's SOFTWARE + default NTUSER hives, write

    values, stage assets, reg-unload. Online: write live HKLM + default-user hive.

    Design: ../docs/superpowers/specs/2026-06-09-first-boot-branding-design.md

#>

[CmdletBinding()]

param(

    [Parameter(Mandatory)][ValidateSet('Offline','Online')][string]$Mode,

    [string]$MountPath,                                   # required for Offline

    [string]$Manifest  = "$PSScriptRoot\branding.manifest.json",

    [string]$AssetsDir = "$PSScriptRoot\assets",

    [switch]$PassThru

)

Set-StrictMode -Version Latest

$ErrorActionPreference = 'Stop'

. "$PSScriptRoot\lib\BrandingLayers.ps1"

function Write-Stage { param($m) Write-Host "==> $m" -ForegroundColor Cyan }



if ($Mode -eq 'Offline' -and -not $MountPath) { throw 'Offline mode requires -MountPath.' }

$m = Get-Content $Manifest -Raw | ConvertFrom-Json



# Destination paths (image-relative for offline, live for online).

$winRoot   = if ($Mode -eq 'Offline') { $MountPath } else { 'C:' }

$logoDest  = Join-Path $winRoot 'Windows\System32\oemlogo.bmp'

$lockDir   = Join-Path $winRoot 'Windows\Web\Screen\SilverMetal'

$wallDir   = Join-Path $winRoot 'Windows\Web\Wallpaper\SilverMetal'

$themeDest = Join-Path $winRoot 'Windows\Resources\Themes'

$lockLive  = 'C:\Windows\Web\Screen\SilverMetal\'   + $m.lockScreen.image

$wallLive  = 'C:\Windows\Web\Wallpaper\SilverMetal\' + $m.desktop.wallpaper

$logoLive  = 'C:\Windows\System32\oemlogo.bmp'



# --- stage assets ---

Write-Stage "Stage branding assets ($Mode)"

New-Item -ItemType Directory -Force $lockDir,$wallDir,$themeDest,(Split-Path $logoDest) | Out-Null

Copy-Item (Join-Path $AssetsDir $m.oem.logo)        $logoDest -Force

Copy-Item (Join-Path $AssetsDir $m.lockScreen.image) (Join-Path $lockDir $m.lockScreen.image) -Force

Copy-Item (Join-Path $AssetsDir $m.desktop.wallpaper)(Join-Path $wallDir $m.desktop.wallpaper) -Force

Copy-Item (Join-Path $AssetsDir $m.desktop.theme)    (Join-Path $themeDest $m.desktop.theme) -Force



$result = [ordered]@{ OemApplied=$false; LockScreenApplied=$false; DesktopApplied=$false; BitLockerApplied=$false }



function Invoke-WithHive {

    param([string]$HivePath,[string]$Name,[scriptblock]$Body)

    & reg load "HKLM\$Name" $HivePath | Out-Null

    if ($LASTEXITCODE -ne 0) { throw "reg load $Name ($HivePath) failed" }

    try { & $Body "Registry::HKEY_LOCAL_MACHINE\$Name" }

    finally {

        [gc]::Collect(); Start-Sleep -Milliseconds 500

        & reg unload "HKLM\$Name" | Out-Null

        if ($LASTEXITCODE -ne 0) { Write-Warning "reg unload $Name failed ($LASTEXITCODE) -- hive may be leaked" }

    }

}



if ($Mode -eq 'Offline') {

    $swHive = Join-Path $MountPath 'Windows\System32\config\SOFTWARE'

    $duHive = Join-Path $MountPath 'Users\Default\NTUSER.DAT'

    Invoke-WithHive $swHive 'SM_BRAND_SW' {

        param($sw)

        Write-Stage 'OEM About';        Set-OemInformation  -SoftwareRoot $sw -Manifest $m -LogoPath $logoLive; $result.OemApplied=$true

        Write-Stage 'Lock screen';      Set-LockScreen      -SoftwareRoot $sw -ImagePath $lockLive -Lock:$m.lockScreen.lock; $result.LockScreenApplied=$true

        Write-Stage 'BitLocker preboot';Set-BitLockerPreboot -SoftwareRoot $sw -Manifest $m; $result.BitLockerApplied=$true

    }

    Invoke-WithHive $duHive 'SM_BRAND_DU' {

        param($du)

        Write-Stage 'Desktop'; Set-DesktopBranding -DefaultUserRoot $du -Manifest $m -WallpaperPath $wallLive; $result.DesktopApplied=$true

    }

} else {

    Set-OemInformation  -SoftwareRoot 'HKLM:\SOFTWARE' -Manifest $m -LogoPath $logoLive; $result.OemApplied=$true

    Set-LockScreen      -SoftwareRoot 'HKLM:\SOFTWARE' -ImagePath $lockLive -Lock:$m.lockScreen.lock; $result.LockScreenApplied=$true

    Set-BitLockerPreboot -SoftwareRoot 'HKLM:\SOFTWARE' -Manifest $m; $result.BitLockerApplied=$true

    Invoke-WithHive 'C:\Users\Default\NTUSER.DAT' 'SM_BRAND_DU' {

        param($du) Set-DesktopBranding -DefaultUserRoot $du -Manifest $m -WallpaperPath $wallLive; $result.DesktopApplied=$true

    }

}



Write-Host 'Branding applied.' -ForegroundColor Green

if ($PassThru) { [pscustomobject]$result }

