# Apply-ShopdbDefaultPrinter.ps1
#
# Sets the logged-on user's default printer to the one ShopDB assigned. Runs IN
# THE USER'S CONTEXT, at logon and on a repeat, because a default printer is
# per-user state that SYSTEM cannot set for somebody else.
#
# Set-ShopdbPrinters.ps1 records the desired queue in
# HKLM:\SOFTWARE\GE\ShopDB DefaultPrinter during the enforcement cycle. This
# reads it. Splitting the two is not tidiness: the machine half needs SYSTEM and
# the share, the user half needs a user - no single process has both.
#
# IT ALSO TURNS OFF "Let Windows manage my default printer". Leaving it on means
# Windows silently overwrites the choice the next time somebody prints to another
# queue, and the bay drifts back with nothing in any log to say why.
#
# Converges: when the current default already matches, it does nothing, so a
# repeating trigger costs a registry read. A user who deliberately picks another
# default WILL be corrected on the next run - that is the intent for a shared
# bay. For a PC where that is wrong, schedule it at logon only.
#
# Exits 0 always.

param(
    # Override for testing. Normally read from the machine hive.
    [string]$PrinterName = ''
)

$ErrorActionPreference = 'Continue'

$logDir = "$env:LOCALAPPDATA\ShopDB"
if (-not (Test-Path $logDir)) {
    New-Item -ItemType Directory -Path $logDir -Force -ErrorAction SilentlyContinue | Out-Null
}
$logFile = Join-Path $logDir 'default-printer.log'
function Log([string]$msg) {
    $ts = Get-Date -Format 'yyyy-MM-dd HH:mm:ss'
    "$ts $msg" | Tee-Object -FilePath $logFile -Append | Out-Null
}

if (-not $PrinterName) {
    foreach ($path in @('HKLM:\SOFTWARE\GE\ShopDB', 'HKLM:\SOFTWARE\WOW6432Node\GE\ShopDB')) {
        try {
            if (Test-Path $path) {
                $value = [string](Get-ItemProperty -Path $path -Name DefaultPrinter -ErrorAction Stop).DefaultPrinter
                if ($value -and $value.Trim()) { $PrinterName = $value.Trim(); break }
            }
        } catch {}
    }
}

if (-not $PrinterName) {
    # No default assigned is a legitimate state - a bay with three printers and
    # no favourite - so leave whatever the user has.
    Log 'no default assigned in ShopDB; leaving the current one alone'
    exit 0
}

# Windows 10+ overrides any default the moment the user prints elsewhere, unless
# this is off. Setting the default without clearing this is a fix that undoes
# itself within a day.
try {
    $windowsKey = 'HKCU:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows'
    $managed = (Get-ItemProperty -Path $windowsKey -Name LegacyDefaultPrinterMode -ErrorAction SilentlyContinue).LegacyDefaultPrinterMode
    if ($managed -ne 1) {
        Set-ItemProperty -Path $windowsKey -Name LegacyDefaultPrinterMode -Value 1 -Type DWord
        Log 'turned off "Let Windows manage my default printer"'
    }
} catch {
    Log "WARN could not turn off Windows-managed defaults: $($_.Exception.Message)"
}

$queue = Get-Printer -Name $PrinterName -ErrorAction SilentlyContinue
if (-not $queue) {
    # The enforcement cycle creates queues; this runs at logon and may simply be
    # earlier than the first cycle on a new bay. Next run picks it up.
    Log "assigned default '$PrinterName' is not installed yet; nothing to do"
    exit 0
}

$current = (Get-CimInstance -ClassName Win32_Printer -Filter 'Default = True' -ErrorAction SilentlyContinue).Name
if ($current -eq $PrinterName) {
    Log "already default: $PrinterName"
    exit 0
}

try {
    $target = Get-CimInstance -ClassName Win32_Printer -Filter ("Name = '{0}'" -f $PrinterName.Replace("'", "''")) -ErrorAction Stop
    Invoke-CimMethod -InputObject $target -MethodName SetDefaultPrinter -ErrorAction Stop | Out-Null
    Log "default set: $PrinterName (was '$current')"
} catch {
    Log "ERROR setting the default to '$PrinterName': $($_.Exception.Message)"
}

exit 0
