dist/temp/WindowsUpdateTools/Private/Test-WUWindows11Compatibility.ps1

function Test-WUWindows11Compatibility {
    <#
    .SYNOPSIS
        Tests Windows 11 upgrade compatibility requirements.
 
    .DESCRIPTION
        Comprehensive Windows 11 compatibility assessment checking all major requirements
        including CPU, TPM, Secure Boot, UEFI, memory, storage, and more. Also checks
        for existing Microsoft compatibility holds via registry.
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $compatibility = Test-WUWindows11Compatibility -LogPath "C:\Logs\wu.log"
 
    .NOTES
        This is a private function used internally by the WindowsUpdateTools module.
        Returns detailed Windows 11 compatibility assessment.
    #>


    [CmdletBinding()]
    param(
        [string]$LogPath
    )

    Write-WULog -Message "Starting Windows 11 compatibility assessment" -LogPath $LogPath

    # Initialize results object
    $results = [PSCustomObject]@{
        Compatible = $true
        OverallAssessment = "Compatible"
        Checks = @{}
        FailedChecks = @()
        WarningChecks = @()
        CompatibilityHolds = @()
        SystemInfo = @{}
        Issues = @()
        ErrorMessage = $null
    }

    try {
        # Get current OS info for context
        $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
        $currentBuild = $osInfo.BuildNumber
        
        Write-WULog -Message "Current OS: $($osInfo.Caption) Build $currentBuild" -LogPath $LogPath

        # Check for existing Microsoft compatibility holds first
        Write-WULog -Message "Checking for existing Microsoft compatibility holds..." -LogPath $LogPath
        $compatibilityHolds = Test-WUCompatibilityHolds -LogPath $LogPath
        if ($compatibilityHolds.Count -gt 0) {
            $results.CompatibilityHolds = $compatibilityHolds
            $results.Compatible = $false
            $results.OverallAssessment = "Blocked by Microsoft"
            foreach ($hold in $compatibilityHolds) {
                $results.Issues += "Microsoft compatibility hold: $hold"
            }
        }

        # 1. Architecture Check (64-bit requirement)
        Write-WULog -Message "Checking system architecture..." -LogPath $LogPath
        $archCheck = Test-WUArchitecture -LogPath $LogPath
        $results.Checks["Architecture"] = $archCheck
        if (-not $archCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Architecture"
            $results.Issues += $archCheck.Issue
        }

        # 2. UEFI/Boot Mode Check
        Write-WULog -Message "Checking boot mode (UEFI requirement)..." -LogPath $LogPath
        $bootCheck = Test-WUBootMode -LogPath $LogPath
        $results.Checks["BootMode"] = $bootCheck
        if (-not $bootCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "BootMode"
            $results.Issues += $bootCheck.Issue
        }

        # 3. CPU Compatibility Check
        Write-WULog -Message "Checking CPU compatibility..." -LogPath $LogPath
        $cpuCheck = Test-WUCPUCompatibility -LogPath $LogPath
        $results.Checks["CPU"] = $cpuCheck
        if (-not $cpuCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "CPU"
            $results.Issues += $cpuCheck.Issue
        }

        # 4. Memory Check (4GB minimum)
        Write-WULog -Message "Checking memory requirements..." -LogPath $LogPath
        $memoryCheck = Test-WUMemoryRequirement -LogPath $LogPath
        $results.Checks["Memory"] = $memoryCheck
        if (-not $memoryCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Memory"
            $results.Issues += $memoryCheck.Issue
        }

        # 5. Storage Check (64GB minimum)
        Write-WULog -Message "Checking storage requirements..." -LogPath $LogPath
        $storageCheck = Test-WUStorageRequirement -LogPath $LogPath
        $results.Checks["Storage"] = $storageCheck
        if (-not $storageCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Storage"
            $results.Issues += $storageCheck.Issue
        }

        # 6. TPM Check (2.0 requirement)
        Write-WULog -Message "Checking TPM requirements..." -LogPath $LogPath
        $tpmCheck = Test-WUTPMRequirement -LogPath $LogPath
        $results.Checks["TPM"] = $tpmCheck
        if (-not $tpmCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "TPM"
            $results.Issues += $tpmCheck.Issue
        }

        # 7. Secure Boot Check
        Write-WULog -Message "Checking Secure Boot requirements..." -LogPath $LogPath
        $secureBootCheck = Test-WUSecureBootRequirement -LogPath $LogPath
        $results.Checks["SecureBoot"] = $secureBootCheck
        if (-not $secureBootCheck.Passed) {
            # Secure Boot can be enabled, so this might be a warning rather than failure
            if ($secureBootCheck.CanBeEnabled) {
                $results.WarningChecks += "SecureBoot"
                $results.Issues += "Warning: " + $secureBootCheck.Issue
            } else {
                $results.Compatible = $false
                $results.FailedChecks += "SecureBoot"
                $results.Issues += $secureBootCheck.Issue
            }
        }

        # 8. GPT Disk Check
        Write-WULog -Message "Checking disk partitioning (GPT requirement)..." -LogPath $LogPath
        $diskCheck = Test-WUDiskPartitioning -LogPath $LogPath
        $results.Checks["DiskPartitioning"] = $diskCheck
        if (-not $diskCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "DiskPartitioning"
            $results.Issues += $diskCheck.Issue
        }

        # 9. DirectX 12 Check
        Write-WULog -Message "Checking DirectX 12 requirements..." -LogPath $LogPath
        $dxCheck = Test-WUDirectXRequirement -LogPath $LogPath
        $results.Checks["DirectX12"] = $dxCheck
        if (-not $dxCheck.Passed) {
            if ($dxCheck.IsWarning) {
                $results.WarningChecks += "DirectX12"
                $results.Issues += "Warning: " + $dxCheck.Issue
            } else {
                $results.Compatible = $false
                $results.FailedChecks += "DirectX12"
                $results.Issues += $dxCheck.Issue
            }
        }

        # 10. Internet Connectivity Check (for updates)
        Write-WULog -Message "Checking internet connectivity..." -LogPath $LogPath
        $internetCheck = Test-WUInternetConnectivity -LogPath $LogPath
        $results.Checks["InternetConnectivity"] = $internetCheck
        if (-not $internetCheck.Passed) {
            $results.WarningChecks += "InternetConnectivity"
            $results.Issues += "Warning: " + $internetCheck.Issue
        }

        # Determine overall assessment
        if ($results.CompatibilityHolds.Count -gt 0) {
            $results.OverallAssessment = "Blocked by Microsoft compatibility hold"
        } elseif ($results.FailedChecks.Count -gt 0) {
            $results.OverallAssessment = "Not compatible - $($results.FailedChecks.Count) requirement(s) failed"
            $results.Compatible = $false
        } elseif ($results.WarningChecks.Count -gt 0) {
            $results.OverallAssessment = "Compatible with warnings - $($results.WarningChecks.Count) item(s) need attention"
        } else {
            $results.OverallAssessment = "Fully compatible"
        }

        # Log summary
        Write-WULog -Message "Windows 11 compatibility assessment completed:" -LogPath $LogPath
        Write-WULog -Message " Overall: $($results.OverallAssessment)" -LogPath $LogPath
        Write-WULog -Message " Failed checks: $($results.FailedChecks.Count)" -LogPath $LogPath
        Write-WULog -Message " Warning checks: $($results.WarningChecks.Count)" -LogPath $LogPath
        Write-WULog -Message " Compatibility holds: $($results.CompatibilityHolds.Count)" -LogPath $LogPath

        if ($results.FailedChecks.Count -gt 0) {
            Write-WULog -Message "Failed requirements: $($results.FailedChecks -join ', ')" -Level Warning -LogPath $LogPath
        }

    }
    catch {
        $results.ErrorMessage = $_.Exception.Message
        Write-WULog -Message "Error during Windows 11 compatibility assessment: $($_.Exception.Message)" -Level Error -LogPath $LogPath
    }

    return $results
}
function Test-WUCompatibilityHolds {
    <#
    .SYNOPSIS
        Checks for Microsoft-imposed compatibility holds.
     
    .DESCRIPTION
        Checks registry for Microsoft compatibility holds that would block Windows 11 upgrade.
        Only treats actual blocking reasons as holds, ignoring "None" values.
        Handles both string and string array registry values.
    #>

    param([string]$LogPath)
    
    $holds = @()
    
    try {
        # Check various Windows versions for compatibility holds
        $windowsVersions = @("Windows 11", "22H2", "21H2", "23H2", "24H2")
        
        foreach ($version in $windowsVersions) {
            $regPath = "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\TargetVersionUpgradeExperienceIndicators\$version"
            
            if (Test-Path $regPath) {
                $redReason = Get-ItemProperty -Path $regPath -Name "RedReason" -ErrorAction SilentlyContinue
                if ($redReason -and $redReason.RedReason) {
                    
                    # Handle both string and string array values
                    $reasonValues = @()
                    if ($redReason.RedReason -is [Array]) {
                        # Registry value is REG_MULTI_SZ (string array)
                        $reasonValues = $redReason.RedReason
                        Write-WULog -Message "Found registry array for $version with $($reasonValues.Count) values" -LogPath $LogPath
                    } else {
                        # Registry value is REG_SZ (single string)
                        $reasonValues = @($redReason.RedReason.ToString())
                    }
                    
                    # Check each value to see if it's actually a blocking reason
                    $actualBlocks = @()
                    foreach ($reasonValue in $reasonValues) {
                        $cleanValue = $reasonValue.ToString().Trim()
                        
                        if ($cleanValue -ne "None" -and $cleanValue -ne "" -and $cleanValue -ne $null) {
                            $actualBlocks += $cleanValue
                        }
                    }
                    
                    if ($actualBlocks.Count -gt 0) {
                        foreach ($block in $actualBlocks) {
                            $holds += "Version $version`: $block"
                            Write-WULog -Message "Found compatibility hold for $version`: $block" -Level Warning -LogPath $LogPath
                        }
                    } else {
                        Write-WULog -Message "Found registry entry for $version but all values are 'None' or empty (no actual hold)" -LogPath $LogPath
                    }
                }
            }
        }
        
        if ($holds.Count -eq 0) {
            Write-WULog -Message "No Microsoft compatibility holds found" -LogPath $LogPath
        }
    }
    catch {
        Write-WULog -Message "Error checking compatibility holds: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $holds
}

function Test-WUArchitecture {
    <#
    .SYNOPSIS
        Tests CPU architecture requirements (64-bit).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        $cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1
        $os = Get-CimInstance -ClassName Win32_OperatingSystem
        
        $result.Value = $cpu.Architecture
        $result.Details["CPUArchitecture"] = $cpu.Architecture
        $result.Details["OSArchitecture"] = $os.OSArchitecture
        
        # Check for 64-bit capability
        if ($cpu.Architecture -eq 9) {  # 9 = x64
            $result.Passed = $true
            Write-WULog -Message "Architecture check passed: x64" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires 64-bit (x64) processor architecture"
            Write-WULog -Message "Architecture check failed: $($cpu.Architecture)" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine system architecture"
        Write-WULog -Message "Error checking architecture: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUBootMode {
    <#
    .SYNOPSIS
        Tests UEFI boot mode requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Check firmware type
        $firmwareType = $env:firmware_type
        $result.Value = $firmwareType
        
        if ($firmwareType -eq "UEFI") {
            $result.Passed = $true
            Write-WULog -Message "Boot mode check passed: UEFI" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires UEFI firmware (Legacy BIOS not supported)"
            Write-WULog -Message "Boot mode check failed: $firmwareType" -LogPath $LogPath
        }
        
        $result.Details["FirmwareType"] = $firmwareType
    }
    catch {
        $result.Issue = "Unable to determine boot mode"
        Write-WULog -Message "Error checking boot mode: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUCPUCompatibility {
    <#
    .SYNOPSIS
        Tests CPU compatibility for Windows 11 using simple generation-based logic.
     
    .DESCRIPTION
        Determines CPU compatibility by parsing the CPU name to extract generation.
        Blocks Intel CPUs older than 8th generation and unsupported AMD architectures.
        Uses reliable name-based detection instead of inconsistent WMI properties.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Get CPU information
        $cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1
        
        $result.Value = $cpu.Name
        $result.Details["CPUName"] = $cpu.Name
        $result.Details["Manufacturer"] = $cpu.Manufacturer
        $result.Details["Cores"] = $cpu.NumberOfCores
        $result.Details["LogicalProcessors"] = $cpu.NumberOfLogicalProcessors
        $result.Details["MaxClockSpeed"] = $cpu.MaxClockSpeed
        $result.Details["Architecture"] = $cpu.Architecture
        $result.Details["AddressWidth"] = $cpu.AddressWidth
        
        Write-WULog -Message "CPU: $($cpu.Name), Manufacturer: $($cpu.Manufacturer)" -LogPath $LogPath
        
        # Check basic hardware requirements first
        $issues = @()
        
        # 64-bit requirement
        if ($null -eq $cpu.AddressWidth -or $cpu.AddressWidth -ne 64) {
            $issues += "CPU must support 64-bit addressing (found: $($cpu.AddressWidth)-bit)"
        }
        
        # Speed requirement (1 GHz minimum)
        if ($null -eq $cpu.MaxClockSpeed -or $cpu.MaxClockSpeed -le 1000) {
            $issues += "CPU must be faster than 1 GHz (found: $($cpu.MaxClockSpeed) MHz)"
        }
        
        # Core count requirement (2 logical cores minimum)
        if ($null -eq $cpu.NumberOfLogicalProcessors -or $cpu.NumberOfLogicalProcessors -lt 2) {
            $issues += "CPU must have at least 2 logical cores (found: $($cpu.NumberOfLogicalProcessors))"
        }
        
        # CPU Generation/Model Compatibility Check
        $cpuSupported = $true
        $blockReason = ""
        $detectedGeneration = "Unknown"
        $cpuName = $cpu.Name
        
        if ($cpu.Manufacturer -like "*Intel*" -or $cpu.Manufacturer -eq "GenuineIntel") {
            Write-WULog -Message "Checking Intel CPU compatibility..." -LogPath $LogPath
            
            # Method 1: Modern naming with "Nth Gen" in the name
            if ($cpuName -match "(\d+)th Gen") {
                $generation = [int]$matches[1]
                $detectedGeneration = "${generation}th Generation"
                
                if ($generation -lt 8) {
                    $cpuSupported = $false
                    $blockReason = "Intel ${generation}th generation CPUs not supported (requires 8th generation or newer)"
                }
            }
            # Method 2: Older naming pattern (i3/i5/i7/i9-XXXX) - More robust approach
            elseif ($cpuName -match "i[3579]-(\d{4,5})[A-Z]*") {
                $modelNumber = [int]$matches[1]
                
                # Use numeric comparison to determine generation
                if ($modelNumber -ge 10000) {
                    # 5-digit numbers: 10xxx, 11xxx, 12xxx, etc.
                    $generation = [Math]::Floor($modelNumber / 1000)
                } else {
                    # 4-digit numbers: 1xxx, 2xxx, 3xxx, etc.
                    $generation = [Math]::Floor($modelNumber / 1000)
                }
                
                $detectedGeneration = "${generation}th Generation (model: $modelNumber)"
                
                if ($generation -lt 8) {
                    $cpuSupported = $false
                    $blockReason = "Intel ${generation}th generation CPUs not supported (requires 8th generation or newer)"
                }
            }
            # Method 3: Very old Intel architectures
            elseif ($cpuName -match "(Core 2|Pentium 4|Pentium D|Celeron M|Atom)") {
                $architecture = $matches[1]
                $cpuSupported = $false
                $blockReason = "Intel $architecture architecture not supported for Windows 11"
                $detectedGeneration = "Legacy Intel"
            }
            # Method 4: Other Pentium/Celeron (check for modern variants)
            elseif ($cpuName -match "(Pentium|Celeron)") {
                if ($cpuName -match "(Pentium Gold|Celeron G\d{4})") {
                    $detectedGeneration = "Modern Pentium/Celeron (likely supported)"
                } else {
                    $cpuSupported = $false
                    $blockReason = "Older Pentium/Celeron processors not supported for Windows 11"
                    $detectedGeneration = "Legacy Pentium/Celeron"
                }
            }
            # Method 5: Fallback - couldn't determine generation
            else {
                $detectedGeneration = "Unknown Intel generation"
                Write-WULog -Message "WARNING: Could not determine Intel CPU generation from name: $cpuName" -Level Warning -LogPath $LogPath
            }
        }
        elseif ($cpu.Manufacturer -like "*AMD*" -or $cpu.Manufacturer -eq "AuthenticAMD") {
            Write-WULog -Message "Checking AMD CPU compatibility..." -LogPath $LogPath
            
            # AMD Ryzen series
            if ($cpuName -match "Ryzen.*(\d)(\d{3})") {
                $series = [int]$matches[1]
                $detectedGeneration = "AMD Ryzen ${series}000 series"
                
                # Most Ryzen 2000+ series are supported, some Ryzen 1000 models too
                if ($series -eq 1) {
                    Write-WULog -Message "AMD Ryzen 1000 series - some models may not be supported" -Level Warning -LogPath $LogPath
                    $detectedGeneration += " (verify specific model compatibility)"
                }
            }
            # AMD FX series (older, not supported)
            elseif ($cpuName -match "FX-(\d)(\d{3})") {
                $cpuSupported = $false
                $blockReason = "AMD FX series processors not supported for Windows 11"
                $detectedGeneration = "AMD FX series"
            }
            # Other older AMD architectures
            elseif ($cpuName -match "(Athlon|Phenom|A[4-9]-\d{4})") {
                $architecture = $matches[1]
                $cpuSupported = $false
                $blockReason = "AMD $architecture architecture not supported for Windows 11"
                $detectedGeneration = "Legacy AMD"
            }
            else {
                $detectedGeneration = "AMD (unknown generation)"
                Write-WULog -Message "WARNING: Could not determine AMD CPU generation from name: $cpuName" -Level Warning -LogPath $LogPath
            }
        }
        elseif ($cpu.Manufacturer -like "*Qualcomm*") {
            Write-WULog -Message "ARM processor detected" -LogPath $LogPath
            $detectedGeneration = "ARM Processor"
            # ARM processors - if Windows is running, assume compatible
        }
        else {
            Write-WULog -Message "Unknown CPU manufacturer: $($cpu.Manufacturer)" -Level Warning -LogPath $LogPath
            $detectedGeneration = "Unknown Manufacturer"
        }
        
        # Final decision
        if ($issues.Count -eq 0 -and $cpuSupported) {
            $result.Passed = $true
            Write-WULog -Message "CPU compatibility check PASSED: $($cpu.Name) ($detectedGeneration)" -LogPath $LogPath
        } else {
            if ($issues.Count -gt 0) {
                $result.Issue = $issues -join "; "
            } else {
                $result.Issue = $blockReason
            }
            Write-WULog -Message "CPU compatibility check FAILED: $($result.Issue)" -LogPath $LogPath
        }
        
        $result.Details["DetectedGeneration"] = $detectedGeneration
        $result.Details["SupportStatus"] = if ($cpuSupported) { "Supported" } else { "Not Supported" }
        $result.Details["BlockReason"] = $blockReason
        
    }
    catch {
        $result.Issue = "Error checking CPU compatibility: $($_.Exception.Message)"
        Write-WULog -Message $result.Issue -Level Error -LogPath $LogPath
    }
    
    return $result
}

function Test-WUMemoryRequirement {
    <#
    .SYNOPSIS
        Tests memory requirement (4GB minimum).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = 0
        Issue = ""
        Details = @{}
    }
    
    try {
        # Try to get physically installed memory first
        $physicalMemoryKB = 0
        
        try {
            Add-Type -TypeDefinition @"
                using System;
                using System.Runtime.InteropServices;
                public class MemoryInfo {
                    [DllImport("kernel32.dll")]
                    public static extern bool GetPhysicallyInstalledSystemMemory(out long totalMemoryInKilobytes);
                }
"@

            $totalMemoryKB = 0
            if ([MemoryInfo]::GetPhysicallyInstalledSystemMemory([ref]$totalMemoryKB)) {
                $physicalMemoryKB = $totalMemoryKB
            }
        }
        catch {
            # Fallback to WMI
            $totalMemory = Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum
            $physicalMemoryKB = $totalMemory.Sum / 1KB
        }
        
        $memoryGB = [math]::Round($physicalMemoryKB / 1024 / 1024, 1)
        $result.Value = $memoryGB
        $result.Details["MemoryGB"] = $memoryGB
        $result.Details["MemoryKB"] = $physicalMemoryKB
        
        if ($memoryGB -ge 4) {
            $result.Passed = $true
            Write-WULog -Message "Memory check passed: $memoryGB GB" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires at least 4 GB of RAM (found: $memoryGB GB)"
            Write-WULog -Message "Memory check failed: $memoryGB GB" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine memory capacity"
        Write-WULog -Message "Error checking memory: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUStorageRequirement {
    <#
    .SYNOPSIS
        Tests storage requirement (64GB minimum).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = 0
        Issue = ""
        Details = @{}
    }
    
    try {
        $systemDrive = $env:SystemDrive
        $drive = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $systemDrive }
        
        $totalSizeGB = [math]::Round($drive.Size / 1GB, 1)
        $result.Value = $totalSizeGB
        $result.Details["SystemDrive"] = $systemDrive
        $result.Details["TotalSizeGB"] = $totalSizeGB
        $result.Details["FreeSpaceGB"] = [math]::Round($drive.FreeSpace / 1GB, 1)
        
        if ($totalSizeGB -ge 64) {
            $result.Passed = $true
            Write-WULog -Message "Storage check passed: $totalSizeGB GB" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires at least 64 GB of storage (found: $totalSizeGB GB)"
            Write-WULog -Message "Storage check failed: $totalSizeGB GB" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine storage capacity"
        Write-WULog -Message "Error checking storage: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUTPMRequirement {
    <#
    .SYNOPSIS
        Tests TPM 2.0 requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Check TPM using WMI
        $tpm = Get-CimInstance -Namespace "root\cimv2\security\microsofttpm" -ClassName Win32_Tpm -ErrorAction SilentlyContinue
        
        if ($tpm) {
            $tpmVersion = $tpm.SpecVersion
            $tpmEnabled = $tpm.IsEnabled_InitialValue
            $tpmActivated = $tpm.IsActivated_InitialValue
            
            $result.Details["TPMPresent"] = $true
            $result.Details["TPMVersion"] = $tpmVersion
            $result.Details["TPMEnabled"] = $tpmEnabled
            $result.Details["TPMActivated"] = $tpmActivated
            
            if ($tpmVersion -like "2.0*") {
                if ($tpmEnabled -and $tpmActivated) {
                    $result.Passed = $true
                    $result.Value = $tpmVersion
                    Write-WULog -Message "TPM check passed: Version $tpmVersion (enabled and activated)" -LogPath $LogPath
                } else {
                    $result.Issue = "TPM 2.0 found but not enabled/activated (check BIOS settings)"
                    $result.Value = "$tpmVersion (not ready)"
                    Write-WULog -Message "TPM check failed: TPM 2.0 present but not ready" -LogPath $LogPath
                }
            } else {
                $result.Issue = "Windows 11 requires TPM 2.0 (found: $tpmVersion)"
                $result.Value = $tpmVersion
                Write-WULog -Message "TPM check failed: Version $tpmVersion" -LogPath $LogPath
            }
        } else {
            # Try alternative method
            $tpmStatus = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\TPM" -Name "Start" -ErrorAction SilentlyContinue
            if ($tpmStatus -and $tpmStatus.Start -eq 3) {
                $result.Issue = "TPM service is disabled"
                $result.Details["TPMPresent"] = $false
            } else {
                $result.Issue = "No TPM found (Windows 11 requires TPM 2.0)"
                $result.Details["TPMPresent"] = $false
            }
            Write-WULog -Message "TPM check failed: No TPM detected" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine TPM status"
        Write-WULog -Message "Error checking TPM: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUSecureBootRequirement {
    <#
    .SYNOPSIS
        Tests Secure Boot requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        CanBeEnabled = $false
        Details = @{}
    }
    
    try {
        $secureBootEnabled = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name "UEFISecureBootEnabled" -ErrorAction SilentlyContinue
        
        if ($secureBootEnabled) {
            $enabled = $secureBootEnabled.UEFISecureBootEnabled
            $result.Details["SecureBootEnabled"] = $enabled
            
            if ($enabled -eq 1) {
                $result.Passed = $true
                $result.Value = "Enabled"
                Write-WULog -Message "Secure Boot check passed: Enabled" -LogPath $LogPath
            } else {
                $result.Value = "Disabled"
                $result.CanBeEnabled = $true  # If registry key exists, UEFI supports it
                $result.Issue = "Secure Boot is disabled (can be enabled in UEFI settings)"
                Write-WULog -Message "Secure Boot check warning: Disabled but can be enabled" -LogPath $LogPath
            }
        } else {
            $result.Issue = "Secure Boot not supported (UEFI firmware required)"
            $result.Value = "Not supported"
            Write-WULog -Message "Secure Boot check failed: Not supported" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine Secure Boot status"
        Write-WULog -Message "Error checking Secure Boot: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUDiskPartitioning {
    <#
    .SYNOPSIS
        Tests GPT disk partitioning requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Get system disk information
        $systemDrive = $env:SystemDrive
        $disk = Get-Partition | Where-Object { $_.DriveLetter -eq $systemDrive.TrimEnd(':') } | 
                Get-Disk
        
        if ($disk) {
            $partitionStyle = $disk.PartitionStyle
            $result.Value = $partitionStyle
            $result.Details["PartitionStyle"] = $partitionStyle
            $result.Details["DiskNumber"] = $disk.Number
            
            if ($partitionStyle -eq "GPT") {
                $result.Passed = $true
                Write-WULog -Message "Disk partitioning check passed: GPT" -LogPath $LogPath
            } else {
                $result.Issue = "Windows 11 requires GPT disk partitioning (found: $partitionStyle)"
                Write-WULog -Message "Disk partitioning check failed: $partitionStyle" -LogPath $LogPath
            }
        } else {
            $result.Issue = "Unable to determine disk partitioning scheme"
            Write-WULog -Message "Disk partitioning check failed: Cannot determine scheme" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to check disk partitioning"
        Write-WULog -Message "Error checking disk partitioning: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUDirectXRequirement {
    <#
    .SYNOPSIS
        Tests DirectX 12 requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        IsWarning = $false
        Details = @{}
    }
    
    try {
        # Check DirectX via registry first (faster)
        $dxVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\DirectX" -Name "Version" -ErrorAction SilentlyContinue
        
        if ($dxVersion) {
            $result.Details["DirectXVersion"] = $dxVersion.Version
        }
        
        # Check graphics capabilities
        $graphics = Get-CimInstance -ClassName Win32_VideoController | Where-Object { $_.PNPDeviceID -notlike "*VEN_1414*" } | Select-Object -First 1
        
        if ($graphics) {
            $result.Details["GraphicsCard"] = $graphics.Name
            $result.Details["DriverVersion"] = $graphics.DriverVersion
            $result.Details["DriverDate"] = $graphics.DriverDate
            
            # Basic check - if it's a modern graphics card, it likely supports DX12
            $modernGPU = $graphics.Name -match "(RTX|GTX 1[0-9]|GTX 9[0-9]|RX [4-7][0-9]|Radeon.*[4-7][0-9]|Intel.*Iris|Intel.*UHD|Intel.*Xe)"
            
            if ($modernGPU) {
                $result.Passed = $true
                $result.Value = "Supported"
                Write-WULog -Message "DirectX 12 check passed: Modern GPU detected" -LogPath $LogPath
            } else {
                $result.IsWarning = $true
                $result.Issue = "Graphics card may not support DirectX 12 (manual verification recommended)"
                $result.Value = "Unknown"
                Write-WULog -Message "DirectX 12 check warning: Unable to confirm support" -LogPath $LogPath
            }
        } else {
            $result.IsWarning = $true
            $result.Issue = "No graphics card detected or unable to determine DirectX 12 support"
            Write-WULog -Message "DirectX 12 check warning: No graphics card detected" -LogPath $LogPath
        }
    }
    catch {
        $result.IsWarning = $true
        $result.Issue = "Unable to determine DirectX 12 support"
        Write-WULog -Message "Error checking DirectX 12: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUInternetConnectivity {
    <#
    .SYNOPSIS
        Tests internet connectivity for Windows Updates.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Test connectivity to Microsoft Update servers
        $testUrls = @(
            "https://www.microsoft.com",
            "https://update.microsoft.com",
            "https://windowsupdate.microsoft.com"
        )
        
        $connectedCount = 0
        foreach ($url in $testUrls) {
            try {
                $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
                if ($response.StatusCode -eq 200) {
                    $connectedCount++
                }
            }
            catch {
                # Connection failed to this URL
            }
        }
        
        $result.Details["TestedUrls"] = $testUrls.Count
        $result.Details["SuccessfulConnections"] = $connectedCount
        
        if ($connectedCount -gt 0) {
            $result.Passed = $true
            $result.Value = "Connected"
            Write-WULog -Message "Internet connectivity check passed: $connectedCount/$($testUrls.Count) connections successful" -LogPath $LogPath
        } else {
            $result.Issue = "No internet connectivity detected (required for Windows Updates)"
            $result.Value = "Disconnected"
            Write-WULog -Message "Internet connectivity check failed: No connections successful" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to test internet connectivity"
        Write-WULog -Message "Error checking internet connectivity: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}function Test-WUWindows11Compatibility {
    <#
    .SYNOPSIS
        Tests Windows 11 upgrade compatibility requirements.
 
    .DESCRIPTION
        Comprehensive Windows 11 compatibility assessment checking all major requirements
        including CPU, TPM, Secure Boot, UEFI, memory, storage, and more. Also checks
        for existing Microsoft compatibility holds via registry.
 
    .PARAMETER LogPath
        Path to the log file for detailed logging.
 
    .EXAMPLE
        $compatibility = Test-WUWindows11Compatibility -LogPath "C:\Logs\wu.log"
 
    .NOTES
        This is a private function used internally by the WindowsUpdateTools module.
        Returns detailed Windows 11 compatibility assessment.
    #>


    [CmdletBinding()]
    param(
        [string]$LogPath
    )

    Write-WULog -Message "Starting Windows 11 compatibility assessment" -LogPath $LogPath

    # Initialize results object
    $results = [PSCustomObject]@{
        Compatible = $true
        OverallAssessment = "Compatible"
        Checks = @{}
        FailedChecks = @()
        WarningChecks = @()
        CompatibilityHolds = @()
        SystemInfo = @{}
        Issues = @()
        ErrorMessage = $null
    }

    try {
        # Get current OS info for context
        $osInfo = Get-CimInstance -ClassName Win32_OperatingSystem
        $currentBuild = $osInfo.BuildNumber
        
        Write-WULog -Message "Current OS: $($osInfo.Caption) Build $currentBuild" -LogPath $LogPath

        # Check for existing Microsoft compatibility holds first
        Write-WULog -Message "Checking for existing Microsoft compatibility holds..." -LogPath $LogPath
        $compatibilityHolds = Test-WUCompatibilityHolds -LogPath $LogPath
        if ($compatibilityHolds.Count -gt 0) {
            $results.CompatibilityHolds = $compatibilityHolds
            $results.Compatible = $false
            $results.OverallAssessment = "Blocked by Microsoft"
            foreach ($hold in $compatibilityHolds) {
                $results.Issues += "Microsoft compatibility hold: $hold"
            }
        }

        # 1. Architecture Check (64-bit requirement)
        Write-WULog -Message "Checking system architecture..." -LogPath $LogPath
        $archCheck = Test-WUArchitecture -LogPath $LogPath
        $results.Checks["Architecture"] = $archCheck
        if (-not $archCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Architecture"
            $results.Issues += $archCheck.Issue
        }

        # 2. UEFI/Boot Mode Check
        Write-WULog -Message "Checking boot mode (UEFI requirement)..." -LogPath $LogPath
        $bootCheck = Test-WUBootMode -LogPath $LogPath
        $results.Checks["BootMode"] = $bootCheck
        if (-not $bootCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "BootMode"
            $results.Issues += $bootCheck.Issue
        }

        # 3. CPU Compatibility Check
        Write-WULog -Message "Checking CPU compatibility..." -LogPath $LogPath
        $cpuCheck = Test-WUCPUCompatibility -LogPath $LogPath
        $results.Checks["CPU"] = $cpuCheck
        if (-not $cpuCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "CPU"
            $results.Issues += $cpuCheck.Issue
        }

        # 4. Memory Check (4GB minimum)
        Write-WULog -Message "Checking memory requirements..." -LogPath $LogPath
        $memoryCheck = Test-WUMemoryRequirement -LogPath $LogPath
        $results.Checks["Memory"] = $memoryCheck
        if (-not $memoryCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Memory"
            $results.Issues += $memoryCheck.Issue
        }

        # 5. Storage Check (64GB minimum)
        Write-WULog -Message "Checking storage requirements..." -LogPath $LogPath
        $storageCheck = Test-WUStorageRequirement -LogPath $LogPath
        $results.Checks["Storage"] = $storageCheck
        if (-not $storageCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "Storage"
            $results.Issues += $storageCheck.Issue
        }

        # 6. TPM Check (2.0 requirement)
        Write-WULog -Message "Checking TPM requirements..." -LogPath $LogPath
        $tpmCheck = Test-WUTPMRequirement -LogPath $LogPath
        $results.Checks["TPM"] = $tpmCheck
        if (-not $tpmCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "TPM"
            $results.Issues += $tpmCheck.Issue
        }

        # 7. Secure Boot Check
        Write-WULog -Message "Checking Secure Boot requirements..." -LogPath $LogPath
        $secureBootCheck = Test-WUSecureBootRequirement -LogPath $LogPath
        $results.Checks["SecureBoot"] = $secureBootCheck
        if (-not $secureBootCheck.Passed) {
            # Secure Boot can be enabled, so this might be a warning rather than failure
            if ($secureBootCheck.CanBeEnabled) {
                $results.WarningChecks += "SecureBoot"
                $results.Issues += "Warning: " + $secureBootCheck.Issue
            } else {
                $results.Compatible = $false
                $results.FailedChecks += "SecureBoot"
                $results.Issues += $secureBootCheck.Issue
            }
        }

        # 8. GPT Disk Check
        Write-WULog -Message "Checking disk partitioning (GPT requirement)..." -LogPath $LogPath
        $diskCheck = Test-WUDiskPartitioning -LogPath $LogPath
        $results.Checks["DiskPartitioning"] = $diskCheck
        if (-not $diskCheck.Passed) {
            $results.Compatible = $false
            $results.FailedChecks += "DiskPartitioning"
            $results.Issues += $diskCheck.Issue
        }

        # 9. DirectX 12 Check
        Write-WULog -Message "Checking DirectX 12 requirements..." -LogPath $LogPath
        $dxCheck = Test-WUDirectXRequirement -LogPath $LogPath
        $results.Checks["DirectX12"] = $dxCheck
        if (-not $dxCheck.Passed) {
            if ($dxCheck.IsWarning) {
                $results.WarningChecks += "DirectX12"
                $results.Issues += "Warning: " + $dxCheck.Issue
            } else {
                $results.Compatible = $false
                $results.FailedChecks += "DirectX12"
                $results.Issues += $dxCheck.Issue
            }
        }

        # 10. Internet Connectivity Check (for updates)
        Write-WULog -Message "Checking internet connectivity..." -LogPath $LogPath
        $internetCheck = Test-WUInternetConnectivity -LogPath $LogPath
        $results.Checks["InternetConnectivity"] = $internetCheck
        if (-not $internetCheck.Passed) {
            $results.WarningChecks += "InternetConnectivity"
            $results.Issues += "Warning: " + $internetCheck.Issue
        }

        # Determine overall assessment
        if ($results.CompatibilityHolds.Count -gt 0) {
            $results.OverallAssessment = "Blocked by Microsoft compatibility hold"
        } elseif ($results.FailedChecks.Count -gt 0) {
            $results.OverallAssessment = "Not compatible - $($results.FailedChecks.Count) requirement(s) failed"
            $results.Compatible = $false
        } elseif ($results.WarningChecks.Count -gt 0) {
            $results.OverallAssessment = "Compatible with warnings - $($results.WarningChecks.Count) item(s) need attention"
        } else {
            $results.OverallAssessment = "Fully compatible"
        }

        # Log summary
        Write-WULog -Message "Windows 11 compatibility assessment completed:" -LogPath $LogPath
        Write-WULog -Message " Overall: $($results.OverallAssessment)" -LogPath $LogPath
        Write-WULog -Message " Failed checks: $($results.FailedChecks.Count)" -LogPath $LogPath
        Write-WULog -Message " Warning checks: $($results.WarningChecks.Count)" -LogPath $LogPath
        Write-WULog -Message " Compatibility holds: $($results.CompatibilityHolds.Count)" -LogPath $LogPath

        if ($results.FailedChecks.Count -gt 0) {
            Write-WULog -Message "Failed requirements: $($results.FailedChecks -join ', ')" -Level Warning -LogPath $LogPath
        }

    }
    catch {
        $results.ErrorMessage = $_.Exception.Message
        Write-WULog -Message "Error during Windows 11 compatibility assessment: $($_.Exception.Message)" -Level Error -LogPath $LogPath
    }

    return $results
}

function Test-WUArchitecture {
    <#
    .SYNOPSIS
        Tests CPU architecture requirements (64-bit).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        $cpu = Get-CimInstance -ClassName Win32_Processor | Select-Object -First 1
        $os = Get-CimInstance -ClassName Win32_OperatingSystem
        
        $result.Value = $cpu.Architecture
        $result.Details["CPUArchitecture"] = $cpu.Architecture
        $result.Details["OSArchitecture"] = $os.OSArchitecture
        
        # Check for 64-bit capability
        if ($cpu.Architecture -eq 9) {  # 9 = x64
            $result.Passed = $true
            Write-WULog -Message "Architecture check passed: x64" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires 64-bit (x64) processor architecture"
            Write-WULog -Message "Architecture check failed: $($cpu.Architecture)" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine system architecture"
        Write-WULog -Message "Error checking architecture: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUBootMode {
    <#
    .SYNOPSIS
        Tests UEFI boot mode requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Check firmware type
        $firmwareType = $env:firmware_type
        $result.Value = $firmwareType
        
        if ($firmwareType -eq "UEFI") {
            $result.Passed = $true
            Write-WULog -Message "Boot mode check passed: UEFI" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires UEFI firmware (Legacy BIOS not supported)"
            Write-WULog -Message "Boot mode check failed: $firmwareType" -LogPath $LogPath
        }
        
        $result.Details["FirmwareType"] = $firmwareType
    }
    catch {
        $result.Issue = "Unable to determine boot mode"
        Write-WULog -Message "Error checking boot mode: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUMemoryRequirement {
    <#
    .SYNOPSIS
        Tests memory requirement (4GB minimum).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = 0
        Issue = ""
        Details = @{}
    }
    
    try {
        # Try to get physically installed memory first
        $physicalMemoryKB = 0
        
        try {
            Add-Type -TypeDefinition @"
                using System;
                using System.Runtime.InteropServices;
                public class MemoryInfo {
                    [DllImport("kernel32.dll")]
                    public static extern bool GetPhysicallyInstalledSystemMemory(out long totalMemoryInKilobytes);
                }
"@

            $totalMemoryKB = 0
            if ([MemoryInfo]::GetPhysicallyInstalledSystemMemory([ref]$totalMemoryKB)) {
                $physicalMemoryKB = $totalMemoryKB
            }
        }
        catch {
            # Fallback to WMI
            $totalMemory = Get-CimInstance -ClassName Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum
            $physicalMemoryKB = $totalMemory.Sum / 1KB
        }
        
        $memoryGB = [math]::Round($physicalMemoryKB / 1024 / 1024, 1)
        $result.Value = $memoryGB
        $result.Details["MemoryGB"] = $memoryGB
        $result.Details["MemoryKB"] = $physicalMemoryKB
        
        if ($memoryGB -ge 4) {
            $result.Passed = $true
            Write-WULog -Message "Memory check passed: $memoryGB GB" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires at least 4 GB of RAM (found: $memoryGB GB)"
            Write-WULog -Message "Memory check failed: $memoryGB GB" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine memory capacity"
        Write-WULog -Message "Error checking memory: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUStorageRequirement {
    <#
    .SYNOPSIS
        Tests storage requirement (64GB minimum).
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = 0
        Issue = ""
        Details = @{}
    }
    
    try {
        $systemDrive = $env:SystemDrive
        $drive = Get-CimInstance -ClassName Win32_LogicalDisk | Where-Object { $_.DeviceID -eq $systemDrive }
        
        $totalSizeGB = [math]::Round($drive.Size / 1GB, 1)
        $result.Value = $totalSizeGB
        $result.Details["SystemDrive"] = $systemDrive
        $result.Details["TotalSizeGB"] = $totalSizeGB
        $result.Details["FreeSpaceGB"] = [math]::Round($drive.FreeSpace / 1GB, 1)
        
        if ($totalSizeGB -ge 64) {
            $result.Passed = $true
            Write-WULog -Message "Storage check passed: $totalSizeGB GB" -LogPath $LogPath
        } else {
            $result.Issue = "Windows 11 requires at least 64 GB of storage (found: $totalSizeGB GB)"
            Write-WULog -Message "Storage check failed: $totalSizeGB GB" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine storage capacity"
        Write-WULog -Message "Error checking storage: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUTPMRequirement {
    <#
    .SYNOPSIS
        Tests TPM 2.0 requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Check TPM using WMI
        $tpm = Get-CimInstance -Namespace "root\cimv2\security\microsofttpm" -ClassName Win32_Tpm -ErrorAction SilentlyContinue
        
        if ($tpm) {
            $tpmVersion = $tpm.SpecVersion
            $tpmEnabled = $tpm.IsEnabled_InitialValue
            $tpmActivated = $tpm.IsActivated_InitialValue
            
            $result.Details["TPMPresent"] = $true
            $result.Details["TPMVersion"] = $tpmVersion
            $result.Details["TPMEnabled"] = $tpmEnabled
            $result.Details["TPMActivated"] = $tpmActivated
            
            if ($tpmVersion -like "2.0*") {
                if ($tpmEnabled -and $tpmActivated) {
                    $result.Passed = $true
                    $result.Value = $tpmVersion
                    Write-WULog -Message "TPM check passed: Version $tpmVersion (enabled and activated)" -LogPath $LogPath
                } else {
                    $result.Issue = "TPM 2.0 found but not enabled/activated (check BIOS settings)"
                    $result.Value = "$tpmVersion (not ready)"
                    Write-WULog -Message "TPM check failed: TPM 2.0 present but not ready" -LogPath $LogPath
                }
            } else {
                $result.Issue = "Windows 11 requires TPM 2.0 (found: $tpmVersion)"
                $result.Value = $tpmVersion
                Write-WULog -Message "TPM check failed: Version $tpmVersion" -LogPath $LogPath
            }
        } else {
            # Try alternative method
            $tpmStatus = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\TPM" -Name "Start" -ErrorAction SilentlyContinue
            if ($tpmStatus -and $tpmStatus.Start -eq 3) {
                $result.Issue = "TPM service is disabled"
                $result.Details["TPMPresent"] = $false
            } else {
                $result.Issue = "No TPM found (Windows 11 requires TPM 2.0)"
                $result.Details["TPMPresent"] = $false
            }
            Write-WULog -Message "TPM check failed: No TPM detected" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine TPM status"
        Write-WULog -Message "Error checking TPM: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUSecureBootRequirement {
    <#
    .SYNOPSIS
        Tests Secure Boot requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        CanBeEnabled = $false
        Details = @{}
    }
    
    try {
        $secureBootEnabled = Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\SecureBoot\State" -Name "UEFISecureBootEnabled" -ErrorAction SilentlyContinue
        
        if ($secureBootEnabled) {
            $enabled = $secureBootEnabled.UEFISecureBootEnabled
            $result.Details["SecureBootEnabled"] = $enabled
            
            if ($enabled -eq 1) {
                $result.Passed = $true
                $result.Value = "Enabled"
                Write-WULog -Message "Secure Boot check passed: Enabled" -LogPath $LogPath
            } else {
                $result.Value = "Disabled"
                $result.CanBeEnabled = $true  # If registry key exists, UEFI supports it
                $result.Issue = "Secure Boot is disabled (can be enabled in UEFI settings)"
                Write-WULog -Message "Secure Boot check warning: Disabled but can be enabled" -LogPath $LogPath
            }
        } else {
            $result.Issue = "Secure Boot not supported (UEFI firmware required)"
            $result.Value = "Not supported"
            Write-WULog -Message "Secure Boot check failed: Not supported" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to determine Secure Boot status"
        Write-WULog -Message "Error checking Secure Boot: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUDiskPartitioning {
    <#
    .SYNOPSIS
        Tests GPT disk partitioning requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Get system disk information
        $systemDrive = $env:SystemDrive
        $disk = Get-Partition | Where-Object { $_.DriveLetter -eq $systemDrive.TrimEnd(':') } | 
                Get-Disk
        
        if ($disk) {
            $partitionStyle = $disk.PartitionStyle
            $result.Value = $partitionStyle
            $result.Details["PartitionStyle"] = $partitionStyle
            $result.Details["DiskNumber"] = $disk.Number
            
            if ($partitionStyle -eq "GPT") {
                $result.Passed = $true
                Write-WULog -Message "Disk partitioning check passed: GPT" -LogPath $LogPath
            } else {
                $result.Issue = "Windows 11 requires GPT disk partitioning (found: $partitionStyle)"
                Write-WULog -Message "Disk partitioning check failed: $partitionStyle" -LogPath $LogPath
            }
        } else {
            $result.Issue = "Unable to determine disk partitioning scheme"
            Write-WULog -Message "Disk partitioning check failed: Cannot determine scheme" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to check disk partitioning"
        Write-WULog -Message "Error checking disk partitioning: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUDirectXRequirement {
    <#
    .SYNOPSIS
        Tests DirectX 12 requirement.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        IsWarning = $false
        Details = @{}
    }
    
    try {
        # Check DirectX via registry first (faster)
        $dxVersion = Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\DirectX" -Name "Version" -ErrorAction SilentlyContinue
        
        if ($dxVersion) {
            $result.Details["DirectXVersion"] = $dxVersion.Version
        }
        
        # Check graphics capabilities
        $graphics = Get-CimInstance -ClassName Win32_VideoController | Where-Object { $_.PNPDeviceID -notlike "*VEN_1414*" } | Select-Object -First 1
        
        if ($graphics) {
            $result.Details["GraphicsCard"] = $graphics.Name
            $result.Details["DriverVersion"] = $graphics.DriverVersion
            $result.Details["DriverDate"] = $graphics.DriverDate
            
            # Basic check - if it's a modern graphics card, it likely supports DX12
            $modernGPU = $graphics.Name -match "(RTX|GTX 1[0-9]|GTX 9[0-9]|RX [4-7][0-9]|Radeon.*[4-7][0-9]|Intel.*Iris|Intel.*UHD|Intel.*Xe)"
            
            if ($modernGPU) {
                $result.Passed = $true
                $result.Value = "Supported"
                Write-WULog -Message "DirectX 12 check passed: Modern GPU detected" -LogPath $LogPath
            } else {
                $result.IsWarning = $true
                $result.Issue = "Graphics card may not support DirectX 12 (manual verification recommended)"
                $result.Value = "Unknown"
                Write-WULog -Message "DirectX 12 check warning: Unable to confirm support" -LogPath $LogPath
            }
        } else {
            $result.IsWarning = $true
            $result.Issue = "No graphics card detected or unable to determine DirectX 12 support"
            Write-WULog -Message "DirectX 12 check warning: No graphics card detected" -LogPath $LogPath
        }
    }
    catch {
        $result.IsWarning = $true
        $result.Issue = "Unable to determine DirectX 12 support"
        Write-WULog -Message "Error checking DirectX 12: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}

function Test-WUInternetConnectivity {
    <#
    .SYNOPSIS
        Tests internet connectivity for Windows Updates.
    #>

    param([string]$LogPath)
    
    $result = [PSCustomObject]@{
        Passed = $false
        Value = ""
        Issue = ""
        Details = @{}
    }
    
    try {
        # Test connectivity to Microsoft Update servers
        $testUrls = @(
            "https://www.microsoft.com",
            "https://update.microsoft.com",
            "https://windowsupdate.microsoft.com"
        )
        
        $connectedCount = 0
        foreach ($url in $testUrls) {
            try {
                $response = Invoke-WebRequest -Uri $url -UseBasicParsing -TimeoutSec 10 -ErrorAction Stop
                if ($response.StatusCode -eq 200) {
                    $connectedCount++
                }
            }
            catch {
                # Connection failed to this URL
            }
        }
        
        $result.Details["TestedUrls"] = $testUrls.Count
        $result.Details["SuccessfulConnections"] = $connectedCount
        
        if ($connectedCount -gt 0) {
            $result.Passed = $true
            $result.Value = "Connected"
            Write-WULog -Message "Internet connectivity check passed: $connectedCount/$($testUrls.Count) connections successful" -LogPath $LogPath
        } else {
            $result.Issue = "No internet connectivity detected (required for Windows Updates)"
            $result.Value = "Disconnected"
            Write-WULog -Message "Internet connectivity check failed: No connections successful" -LogPath $LogPath
        }
    }
    catch {
        $result.Issue = "Unable to test internet connectivity"
        Write-WULog -Message "Error checking internet connectivity: $($_.Exception.Message)" -Level Warning -LogPath $LogPath
    }
    
    return $result
}