categories/Power.ps1

# Power category: hibernation, Fast Startup, USB selective suspend, high-performance power
# plan, power throttling. research.md -> power category table.
#
# ponytail: USB selective suspend and the Ultimate Performance plan are applied via powercfg
# and live under scheme-relative registry paths (keyed by the currently active scheme's GUID),
# not a single fixed key our generic registry snapshot/restore can cleanly capture - marked
# Reversible=$false honestly rather than faking a snapshot that wouldn't actually restore
# correctly. Upgrade path: a dedicated "PowerScheme" prior-state type in StateSnapshot.ps1
# that records the previously-active scheme GUID and restores it via `powercfg -setactive`.

function Get-OctaPowerCategory {
    [CmdletBinding()]
    param()
    return [pscustomobject]@{
        Id                          = 'power'
        DisplayName                 = 'Power'
        Description                 = 'Hibernation, Fast Startup, USB suspend, power plan, throttling'
        RequiresElevation           = $true
        ContainsIrreversibleActions = $true
        GetActionsFunction          = 'Get-OctaPowerActions'
        ApplyActionFunction         = 'Set-OctaPowerAction'
    }
}

function Get-OctaPowerActions {
    [CmdletBinding()]
    param()
    $actions = @()

    # Hibernate - Moderate, reversible (registry-backed; powercfg does the actual toggle).
    $hibernateKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Power'
    $currentHibernate = (Get-ItemProperty -Path $hibernateKey -Name 'HibernateEnabled' -ErrorAction SilentlyContinue).HibernateEnabled
    if ($null -eq $currentHibernate -or $currentHibernate -ne 0) {
        $displayCurrent = if ($null -eq $currentHibernate) { '(not set)' } else { $currentHibernate }
        $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$hibernateKey|HibernateEnabled" `
            -CurrentValue $displayCurrent -PlannedValue 0 -Reversible $true -RiskLevel Moderate
    }

    # Fast Startup - Safe, plain registry DWORD.
    $fastStartupKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power'
    $currentFastStartup = (Get-ItemProperty -Path $fastStartupKey -Name 'HiberbootEnabled' -ErrorAction SilentlyContinue).HiberbootEnabled
    if ($null -eq $currentFastStartup -or $currentFastStartup -ne 0) {
        $displayCurrent = if ($null -eq $currentFastStartup) { '(not set)' } else { $currentFastStartup }
        $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$fastStartupKey|HiberbootEnabled" `
            -CurrentValue $displayCurrent -PlannedValue 0 -Reversible $true -RiskLevel Safe
    }

    # USB selective suspend - Safe, but not cleanly snapshot-restorable today (see ponytail note).
    $actions += New-OctaAction -TargetType Registry -TargetIdentifier 'powercfg|usb-selective-suspend' `
        -CurrentValue 'Enabled' -PlannedValue 'Disabled' -Reversible $false -RiskLevel Safe `
        -IrreversibleReason 'Applied via powercfg against the active power scheme; use the System Restore Point to revert.'

    # Ultimate Performance power plan - Safe, same caveat as above.
    $activeSchemeName = (powercfg /getactivescheme) -join ' '
    if ($activeSchemeName -notmatch 'Ultimate Performance') {
        $actions += New-OctaAction -TargetType Registry -TargetIdentifier 'powercfg|ultimate-performance-plan' `
            -CurrentValue $activeSchemeName -PlannedValue 'Ultimate Performance' -Reversible $false -RiskLevel Safe `
            -IrreversibleReason 'Switches the active power plan via powercfg; use the System Restore Point (or manually reselect your prior plan) to revert.'
    }

    # Power throttling - Moderate, plain registry DWORD.
    $throttleKey = 'HKLM:\SYSTEM\CurrentControlSet\Control\Power\PowerThrottling'
    $currentThrottle = (Get-ItemProperty -Path $throttleKey -Name 'PowerThrottlingOff' -ErrorAction SilentlyContinue).PowerThrottlingOff
    if ($null -eq $currentThrottle -or $currentThrottle -ne 1) {
        $displayCurrent = if ($null -eq $currentThrottle) { '(not set)' } else { $currentThrottle }
        $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$throttleKey|PowerThrottlingOff" `
            -CurrentValue $displayCurrent -PlannedValue 1 -Reversible $true -RiskLevel Moderate
    }

    return $actions
}

function Set-OctaPowerAction {
    [CmdletBinding()]
    param([Parameter(Mandatory)]$Action)

    switch -Wildcard ($Action.TargetIdentifier) {
        'powercfg|usb-selective-suspend' {
            powercfg /setacvalueindex scheme_current 2a737441-1930-4402-8d77-b2bebba308a3 48e6b7a6-50f5-4782-a5d4-53bb8f07e226 0 | Out-Null
            powercfg /setdcvalueindex scheme_current 2a737441-1930-4402-8d77-b2bebba308a3 48e6b7a6-50f5-4782-a5d4-53bb8f07e226 0 | Out-Null
            powercfg /setactive scheme_current | Out-Null
        }
        'powercfg|ultimate-performance-plan' {
            $output = powercfg -duplicatescheme e9a42b02-d5df-448d-aa00-03f14749eb61
            if ($output -match '([0-9a-fA-F-]{36})') {
                powercfg -setactive $Matches[1] | Out-Null
            }
        }
        'HKLM:\SYSTEM\CurrentControlSet\Control\Power|HibernateEnabled' {
            powercfg /hibernate off | Out-Null
        }
        default {
            $keyPath, $valueName = $Action.TargetIdentifier -split '\|', 2
            if (-not (Test-Path $keyPath)) {
                New-Item -Path $keyPath -Force | Out-Null
            }
            Set-ItemProperty -Path $keyPath -Name $valueName -Value $Action.PlannedValue -Type DWord
        }
    }
}