Set-StrictMode -Version Latest

$ErrorActionPreference = 'Stop'

. "$PSScriptRoot\RegistryHelpers.ps1"



function Set-OemInformation {

    param([Parameter(Mandatory)][string]$SoftwareRoot,[Parameter(Mandatory)]$Manifest,[Parameter(Mandatory)][string]$LogoPath)

    $sub = 'Microsoft\Windows\CurrentVersion\OEMInformation'

    Set-SmRegValue -Root $SoftwareRoot -SubKey $sub -Name 'Manufacturer' -Type String -Value $Manifest.oem.manufacturer

    Set-SmRegValue -Root $SoftwareRoot -SubKey $sub -Name 'Model'        -Type String -Value $Manifest.oem.model

    Set-SmRegValue -Root $SoftwareRoot -SubKey $sub -Name 'SupportURL'   -Type String -Value $Manifest.oem.supportUrl

    Set-SmRegValue -Root $SoftwareRoot -SubKey $sub -Name 'SupportHours' -Type String -Value $Manifest.oem.supportHours

    Set-SmRegValue -Root $SoftwareRoot -SubKey $sub -Name 'Logo'         -Type String -Value $LogoPath

}



function Set-LockScreen {

    param([Parameter(Mandatory)][string]$SoftwareRoot,[Parameter(Mandatory)][string]$ImagePath,[bool]$Lock=$true)

    # Per-device modern lock-screen image (reliable on Enterprise/IoT).

    $csp = 'Microsoft\Windows\CurrentVersion\PersonalizationCSP'

    Set-SmRegValue -Root $SoftwareRoot -SubKey $csp -Name 'LockScreenImagePath'   -Type String -Value $ImagePath

    Set-SmRegValue -Root $SoftwareRoot -SubKey $csp -Name 'LockScreenImageUrl'    -Type String -Value $ImagePath

    Set-SmRegValue -Root $SoftwareRoot -SubKey $csp -Name 'LockScreenImageStatus' -Type DWord  -Value 1

    if ($Lock) {

        $pol = 'Policies\Microsoft\Windows\Personalization'

        Set-SmRegValue -Root $SoftwareRoot -SubKey $pol -Name 'LockScreenImage'     -Type String -Value $ImagePath

        Set-SmRegValue -Root $SoftwareRoot -SubKey $pol -Name 'NoChangingLockScreen' -Type DWord  -Value 1

    }

}



function Set-DesktopBranding {

    param([Parameter(Mandatory)][string]$DefaultUserRoot,[Parameter(Mandatory)]$Manifest,[Parameter(Mandatory)][string]$WallpaperPath)

    Set-SmRegValue -Root $DefaultUserRoot -SubKey 'Control Panel\Desktop' -Name 'WallPaper'      -Type String -Value $WallpaperPath

    Set-SmRegValue -Root $DefaultUserRoot -SubKey 'Control Panel\Desktop' -Name 'WallpaperStyle' -Type String -Value '10'   # fill

    if ($Manifest.desktop.darkMode) {

        $p = 'Software\Microsoft\Windows\CurrentVersion\Themes\Personalize'

        Set-SmRegValue -Root $DefaultUserRoot -SubKey $p -Name 'AppsUseLightTheme'   -Type DWord -Value 0

        Set-SmRegValue -Root $DefaultUserRoot -SubKey $p -Name 'SystemUsesLightTheme' -Type DWord -Value 0

    }

    # Accent (cyan). DWM uses fully-opaque DWORDs with DIFFERENT byte orders:

    #   ColorizationColor = 0xAARRGGBB (ARGB);  AccentColor = 0xAABBGGRR (ABGR).

    # Manifest holds the plain RGB hex (source of truth); derive both, alpha=FF.

    # NOTE: exact accent rendering is VM-verified (plan §9 soft spot).

    $rgb = $Manifest.desktop.accentColor.TrimStart('#')

    $r = [Convert]::ToInt32($rgb.Substring(0,2),16)

    $g = [Convert]::ToInt32($rgb.Substring(2,2),16)

    $b = [Convert]::ToInt32($rgb.Substring(4,2),16)

    $argb = [int](0xFF000000 -bor ($r -shl 16) -bor ($g -shl 8) -bor $b)   # ColorizationColor

    $abgr = [int](0xFF000000 -bor ($b -shl 16) -bor ($g -shl 8) -bor $r)   # AccentColor

    Set-SmRegValue -Root $DefaultUserRoot -SubKey 'Software\Microsoft\Windows\DWM' -Name 'AccentColor'       -Type DWord -Value $abgr

    Set-SmRegValue -Root $DefaultUserRoot -SubKey 'Software\Microsoft\Windows\DWM' -Name 'ColorizationColor' -Type DWord -Value $argb

    if (-not $Manifest.desktop.lockWallpaper) { return }

    Set-SmRegValue -Root $DefaultUserRoot -SubKey 'Software\Microsoft\Windows\CurrentVersion\Policies\ActiveDesktop' -Name 'NoChangingWallPaper' -Type DWord -Value 1

}



function Set-BitLockerPreboot {

    param([Parameter(Mandatory)][string]$SoftwareRoot,[Parameter(Mandatory)]$Manifest)

    # GPO "Configure pre-boot recovery message and URL" (ADMX VolumeEncryption).

    # NOTE: only the BitLocker RECOVERY screen is customisable; the normal PIN-entry

    # screen text is fixed Windows UI. Exact value names are asserted by the read-back

    # test; if a name is wrong the offline-apply verify (Task A4) catches it.

    $fve = 'Policies\Microsoft\FVE'

    Set-SmRegValue -Root $SoftwareRoot -SubKey $fve -Name 'UseCustomRecoveryMessage' -Type DWord  -Value 1

    Set-SmRegValue -Root $SoftwareRoot -SubKey $fve -Name 'RecoveryMessage'          -Type String -Value $Manifest.bitlocker.recoveryMessage

    Set-SmRegValue -Root $SoftwareRoot -SubKey $fve -Name 'UseCustomRecoveryUrl'     -Type DWord  -Value 1

    Set-SmRegValue -Root $SoftwareRoot -SubKey $fve -Name 'RecoveryUrl'              -Type String -Value $Manifest.bitlocker.recoveryUrl

}

