# RescuePC Protected Module - DO NOT EDIT
# Source code is maintained separately in the development repository.

$script:StoppedServices = @()
$script:InProgressFile = "$env:TEMP\rescuepc_in_progress.json"

function Test-IsAdministrator {
    $identity = [Security.Principal.WindowsIdentity]::GetCurrent()
    $principal = New-Object Security.Principal.WindowsPrincipal($identity)
    return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}

function Test-LegacyOS {
    $os = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction SilentlyContinue
    if (-not $os) { return $false }

    $build = [int]$os.BuildNumber
    if ($build -lt 10240) {
        Write-Warning "[SAFETY] Legacy OS detected (Build $build). Some repairs may not work correctly."
        return $true
    }
    return $false
}

function Test-WindowsSMode {
    try {
        $sku = (Get-CimInstance -ClassName Win32_OperatingSystem).OperatingSystemSKU
        $sModeSkus = @(178, 179, 189, 191)
        if ($sku -in $sModeSkus) {
            Write-Warning "[SAFETY] Windows S Mode detected. PowerShell scripts are blocked. Please switch out of S Mode."
            return $true
        }

        $sMode = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\CI\Policy" -Name "SkuPolicyRequired" -ErrorAction SilentlyContinue
        if ($sMode.SkuPolicyRequired -eq 1) {
            Write-Warning "[SAFETY] Windows S Mode detected via policy. PowerShell scripts are blocked."
            return $true
        }
    } catch {
    }
    return $false
}

function Test-BitLockerActive {
    param(
        [string]$DriveLetter = $env:SystemDrive
    )

    try {
        $blv = Get-BitLockerVolume -MountPoint $DriveLetter -ErrorAction SilentlyContinue
        if ($blv) {
            if ($blv.EncryptionPercentage -gt 0 -and $blv.EncryptionPercentage -lt 100) {
                Write-Warning "[SAFETY] BitLocker encryption in progress ($($blv.EncryptionPercentage)%). Some repairs may be risky."
                return $true
            }
            if ($blv.VolumeStatus -eq 'EncryptionInProgress' -or $blv.VolumeStatus -eq 'DecryptionInProgress') {
                Write-Warning "[SAFETY] BitLocker operation in progress. Some repairs may be risky."
                return $true
            }
        }
    } catch {
    }
    return $false
}

function Test-ARM64System {
    $arch = $env:PROCESSOR_ARCHITECTURE
    if ($arch -eq 'ARM64') {
        Write-Warning "[SAFETY] ARM64 system detected. Some driver repairs may not be compatible."
        return $true
    }
    return $false
}

function Test-SystemSafety {
    param(
        [switch]$Quiet
    )

    $results = @{
        IsAdmin = Test-IsAdministrator
        IsLegacyOS = Test-LegacyOS
        IsSMode = Test-WindowsSMode
        IsBitLockerActive = Test-BitLockerActive
        IsARM64 = Test-ARM64System
        CanProceed = $true
        Warnings = @()
    }

    if ($results.IsSMode) {
        $results.CanProceed = $false
        $results.Warnings += "Windows S Mode blocks PowerShell scripts"
    }

    if (-not $results.IsAdmin) {
        $results.CanProceed = $false
        $results.Warnings += "Administrator privileges required"
    }

    if ($results.IsLegacyOS) {
        $results.Warnings += "Legacy OS may have limited compatibility"
    }
    if ($results.IsBitLockerActive) {
        $results.Warnings += "BitLocker operation in progress"
    }
    if ($results.IsARM64) {
        $results.Warnings += "ARM64 system - some drivers may not be compatible"
    }

    if (-not $Quiet -and $results.Warnings.Count -gt 0) {
        Write-Host "[SAFETY CHECK] Warnings:" -ForegroundColor Yellow
        foreach ($w in $results.Warnings) {
            Write-Host "  - $w" -ForegroundColor Yellow
        }
    }

    return $results
}

function Start-SafeServiceStop {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [string]$ServiceName,

        [Parameter()]
        [switch]$Force
    )

    try {
        $svc = Get-Service -Name $ServiceName -ErrorAction SilentlyContinue
        if (-not $svc) {
            Write-Warning "[SAFETY] Service not found: $ServiceName"
            return $false
        }

        if ($svc.Status -eq 'Running') {
            $script:StoppedServices += @{
                Name = $ServiceName
                OriginalStatus = $svc.Status
                StoppedAt = (Get-Date).ToString('o')
            }

            Update-InProgressFile

            Stop-Service -Name $ServiceName -Force:$Force -ErrorAction Stop
            Write-Host "[SAFETY] Stopped service: $ServiceName" -ForegroundColor Yellow
            return $true
        } else {
            Write-Host "[SAFETY] Service already stopped: $ServiceName ($($svc.Status))" -ForegroundColor Gray
            return $true
        }
    } catch {
        Write-Error "[SAFETY] Failed to stop service $ServiceName : $_"
        return $false
    }
}

function Complete-SafeServiceRestart {
    [CmdletBinding()]
    param(
        [Parameter()]
        [switch]$All
    )

    if ($script:StoppedServices.Count -eq 0) {
        return
    }

    Write-Host "[SAFETY] Restarting $($script:StoppedServices.Count) stopped service(s)..." -ForegroundColor Cyan

    foreach ($svcInfo in $script:StoppedServices) {
        try {
            $svc = Get-Service -Name $svcInfo.Name -ErrorAction SilentlyContinue
            if ($svc -and $svc.Status -ne 'Running') {
                Start-Service -Name $svcInfo.Name -ErrorAction Stop
                Write-Host "[SAFETY] Restarted service: $($svcInfo.Name)" -ForegroundColor Green
            }
        } catch {
            Write-Warning "[SAFETY] Failed to restart service $($svcInfo.Name): $_"
        }
    }

    $script:StoppedServices = @()

    Remove-InProgressFile
}

function Update-InProgressFile {
    $data = @{
        StartedAt = (Get-Date).ToString('o')
        ScriptName = $MyInvocation.ScriptName
        StoppedServices = $script:StoppedServices
        PID = $PID
    }
    $data | ConvertTo-Json -Depth 3 | Set-Content -Path $script:InProgressFile -Force
}

function Remove-InProgressFile {
    if (Test-Path -LiteralPath $script:InProgressFile) {
        Remove-Item -LiteralPath $script:InProgressFile -Force -ErrorAction SilentlyContinue
    }
}

function Invoke-WithServiceSafety {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [scriptblock]$ScriptBlock,

        [Parameter()]
        [string[]]$ServicesToStop = @()
    )

    try {
        foreach ($svc in $ServicesToStop) {
            Start-SafeServiceStop -ServiceName $svc | Out-Null
        }

        & $ScriptBlock
    }
    finally {
        Complete-SafeServiceRestart
    }
}

function Restore-FromCrash {
    [CmdletBinding()]
    param()

    if (-not (Test-Path -LiteralPath $script:InProgressFile)) {
        return $false
    }

    try {
        $data = Get-Content -Path $script:InProgressFile -Raw | ConvertFrom-Json
        Write-Host "[RECOVERY] Found incomplete repair from $($data.StartedAt)" -ForegroundColor Yellow

        if ($data.StoppedServices -and $data.StoppedServices.Count -gt 0) {
            Write-Host "[RECOVERY] Restarting $($data.StoppedServices.Count) orphaned service(s)..." -ForegroundColor Yellow

            foreach ($svcInfo in $data.StoppedServices) {
                try {
                    $svc = Get-Service -Name $svcInfo.Name -ErrorAction SilentlyContinue
                    if ($svc -and $svc.Status -ne 'Running') {
                        Start-Service -Name $svcInfo.Name -ErrorAction Stop
                        Write-Host "[RECOVERY] Restarted: $($svcInfo.Name)" -ForegroundColor Green
                    }
                } catch {
                    Write-Warning "[RECOVERY] Could not restart $($svcInfo.Name): $_"
                }
            }
        }

        Remove-InProgressFile
        return $true
    } catch {
        Write-Warning "[RECOVERY] Failed to process crash recovery: $_"
        Remove-InProgressFile
        return $false
    }
}

Export-ModuleMember -Function Start-SafeServiceStop, Complete-SafeServiceRestart, Invoke-WithServiceSafety, Restore-FromCrash, Test-IsAdministrator, Test-LegacyOS, Test-WindowsSMode, Test-BitLockerActive, Test-ARM64System, Test-SystemSafety