dist/temp/WindowsUpdateTools/Private/Get-WUWindows11ISO-PS51.ps1

function Get-WUWindows11ISO {
    <#
    .SYNOPSIS
        Downloads the latest Windows 11 ISO from Microsoft with PowerShell 5.1 compatibility
     
    .DESCRIPTION
        This function downloads the latest Windows 11 ISO file from Microsoft using multiple
        methods including Fido, UUP dump, and the official Media Creation Tool. It supports
        multiple languages and editions, with automatic fallback mechanisms and enhanced
        reliability features including retry logic and PowerShell 5.1 compatibility.
     
    .PARAMETER OutputPath
        Directory where the ISO file should be saved. Defaults to current directory.
     
    .PARAMETER Language
        Language code for the Windows 11 ISO (e.g., 'en-us', 'de-de', 'fr-fr').
        Defaults to system language or 'en-us' if system language not supported.
     
    .PARAMETER Edition
        Windows 11 edition to download. Defaults to 'Professional'.
        Valid options: Home, Professional, Education, Enterprise
     
    .PARAMETER Architecture
        System architecture. Defaults to 'x64'.
        Valid options: x64, arm64
     
    .PARAMETER Method
        Download method to use. If not specified, will try methods in order of preference.
        Valid options: Fido, UUP, MediaCreationTool, Auto
     
    .PARAMETER SkipVerification
        Skip file verification after download
     
    .PARAMETER Force
        Overwrite existing ISO files
     
    .PARAMETER MaxRetries
        Maximum number of retry attempts for failed downloads. Defaults to 3.
     
    .PARAMETER RetryDelay
        Delay in seconds between retry attempts. Defaults to 10.
     
    .EXAMPLE
        Get-WUWindows11ISO -OutputPath "C:\ISOs"
        Downloads Windows 11 Professional x64 in system language to C:\ISOs
     
    .EXAMPLE
        Get-WUWindows11ISO -Language "de-de" -Edition "Enterprise" -Method "Fido"
        Downloads Windows 11 Enterprise x64 in German using Fido method
     
    .NOTES
        Requires internet connection and sufficient disk space (5+ GB)
        Enhanced for PowerShell 5.1 compatibility with improved retry logic
        Some methods may require PowerShell to be run as Administrator
    #>

    
    [CmdletBinding()]
    param(
        [Parameter()]
        [string]$OutputPath = (Get-Location).Path,
        
        [Parameter()]
        [string]$Language,
        
        [Parameter()]
        [ValidateSet('Home', 'Professional', 'Education', 'Enterprise')]
        [string]$Edition = 'Professional',
        
        [Parameter()]
        [ValidateSet('x64', 'arm64')]
        [string]$Architecture = 'x64',
        
        [Parameter()]
        [ValidateSet('Fido', 'UUP', 'MediaCreationTool', 'Auto')]
        [string]$Method = 'Auto',
        
        [Parameter()]
        [switch]$SkipVerification,
        
        [Parameter()]
        [switch]$Force,
        
        [Parameter()]
        [int]$MaxRetries = 3,
        
        [Parameter()]
        [int]$RetryDelay = 10
    )
    
    # PowerShell 5.1 compatible TLS setup
    try {
        Write-WULog "Configuring TLS for PowerShell 5.1 compatibility" -Level Info
        [System.Net.ServicePointManager]::SecurityProtocol = 'Tls12'
        Write-WULog "TLS 1.2 configured successfully" -Level Info
    } catch {
        Write-WULog "Failed to configure TLS 1.2: $($_.Exception.Message)" -Level Warning
        try {
            # Fallback method for older systems
            [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
        } catch {
            Write-WULog "TLS configuration fallback also failed. Downloads may fail." -Level Error
        }
    }
    
    Write-WULog "Starting Windows 11 ISO download process (Enhanced PS 5.1 compatible version)" -Level Info
    
    # Validate and create output directory
    if (-not (Test-Path $OutputPath)) {
        try {
            New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
            Write-WULog "Created output directory: $OutputPath" -Level Info
        }
        catch {
            Write-Error "Failed to create output directory: $($_.Exception.Message)"
            return $null
        }
    }
    
    # Auto-detect system language if not specified
    if (-not $Language) {
        $Language = Get-WUSystemLanguageEnhanced
        Write-WULog "Auto-detected system language: $Language" -Level Info
    }
    
    # Define download methods in order of preference
    $downloadMethods = if ($Method -eq 'Auto') {
        @('Fido', 'MediaCreationTool', 'UUP')
    } else {
        @($Method)
    }
    
    $isoFile = $null
    $lastError = $null
    $globalRetryCount = 0
    $maxGlobalRetries = $MaxRetries
    
    # Global retry loop for all methods
    while ($globalRetryCount -lt $maxGlobalRetries -and (-not $isoFile -or -not (Test-Path $isoFile))) {
        $globalRetryCount++
        
        if ($globalRetryCount -gt 1) {
            Write-WULog "Global retry attempt $globalRetryCount of $maxGlobalRetries" -Level Info
            Start-Sleep -Seconds $RetryDelay
        }
        
        foreach ($currentMethod in $downloadMethods) {
            Write-WULog "Attempting download using method: $currentMethod (Global attempt: $globalRetryCount)" -Level Info
            
            $methodRetryCount = 0
            $methodSuccess = $false
            
            # Method-specific retry loop
            while ($methodRetryCount -lt $MaxRetries -and -not $methodSuccess) {
                $methodRetryCount++
                
                if ($methodRetryCount -gt 1) {
                    Write-WULog "Method $currentMethod retry attempt $methodRetryCount of $MaxRetries" -Level Info
                    Start-Sleep -Seconds $RetryDelay
                }
                
                try {
                    switch ($currentMethod) {
                        'Fido' {
                            $isoFile = Invoke-FidoDownloadEnhanced -OutputPath $OutputPath -Language $Language -Edition $Edition -Architecture $Architecture -Force:$Force
                        }
                        'UUP' {
                            $isoFile = Invoke-UUPDownloadEnhanced -OutputPath $OutputPath -Language $Language -Edition $Edition -Architecture $Architecture -Force:$Force
                        }
                        'MediaCreationTool' {
                            $isoFile = Invoke-MediaCreationToolDownloadEnhanced -OutputPath $OutputPath -Language $Language -Edition $Edition -Architecture $Architecture -Force:$Force
                        }
                    }
                    
                    if ($isoFile -and (Test-Path $isoFile)) {
                        Write-WULog "Successfully downloaded Windows 11 ISO using $currentMethod method: $isoFile" -Level Info
                        $methodSuccess = $true
                        break
                    }
                }
                catch {
                    $lastError = $_.Exception
                    Write-WULog "Method $currentMethod attempt $methodRetryCount failed: $($_.Exception.Message)" -Level Warning
                    
                    # Check for specific Microsoft server restrictions
                    if ($_.Exception.Message -match "403|forbidden|rate.?limit|too.?many.?requests") {
                        Write-WULog "Detected Microsoft server restrictions. Waiting longer before retry..." -Level Warning
                        Start-Sleep -Seconds ($RetryDelay * 2)
                    }
                }
            }
            
            if ($methodSuccess) {
                break
            }
        }
        
        if ($isoFile -and (Test-Path $isoFile)) {
            break
        }
        
        if ($globalRetryCount -lt $maxGlobalRetries) {
            Write-WULog "All methods failed in attempt $globalRetryCount. Will retry all methods after delay..." -Level Warning
        }
    }
    
    if (-not $isoFile -or -not (Test-Path $isoFile)) {
        $errorMessage = "All download methods failed after $globalRetryCount global attempts."
        if ($lastError) {
            $errorMessage += " Last error: $($lastError.Message)"
        }
        Write-Error $errorMessage
        return $null
    }
    
    # Verify downloaded ISO file
    if (-not $SkipVerification) {
        Write-WULog "Verifying downloaded ISO file..." -Level Info
        
        if (-not (Test-ISOFileEnhanced -Path $isoFile)) {
            Write-Error "Downloaded ISO file failed verification"
            return $null
        }
        
        Write-WULog "ISO file verification passed" -Level Info
    }
    
    # Return the downloaded ISO file information
    $isoInfo = Get-Item $isoFile
    $result = [PSCustomObject]@{
        Path = $isoInfo.FullName
        Name = $isoInfo.Name
        Size = [math]::Round($isoInfo.Length / 1GB, 2)
        Language = $Language
        Edition = $Edition
        Architecture = $Architecture
        Method = $currentMethod
        DownloadDate = Get-Date
        RetryCount = $globalRetryCount
    }
    
    Write-WULog "Windows 11 ISO download completed successfully after $globalRetryCount global attempts" -Level Info
    return $result
}

#region Enhanced Helper Functions

function Get-WUSystemLanguageEnhanced {
    <#
    .SYNOPSIS
        Gets the system language code suitable for Windows ISO downloads (Enhanced)
    #>

    
    try {
        # Get system locale with multiple methods for reliability
        $systemLocale = $null
        
        try {
            $systemLocale = Get-Culture
        } catch {
            try {
                $systemLocale = [System.Globalization.CultureInfo]::CurrentCulture
            } catch {
                Write-WULog "Could not determine system culture, using en-us" -Level Warning
                return 'en-us'
            }
        }
        
        $languageTag = $systemLocale.Name.ToLower()
        
        # Enhanced language mapping with more comprehensive coverage
        $languageMap = @{
            'en-us' = 'en-us'; 'en-gb' = 'en-gb'; 'en-ca' = 'en-us'; 'en-au' = 'en-us'
            'de-de' = 'de-de'; 'de-at' = 'de-de'; 'de-ch' = 'de-de'
            'fr-fr' = 'fr-fr'; 'fr-ca' = 'fr-fr'; 'fr-be' = 'fr-fr'; 'fr-ch' = 'fr-fr'
            'es-es' = 'es-es'; 'es-mx' = 'es-es'; 'es-ar' = 'es-es'; 'es-co' = 'es-es'
            'it-it' = 'it-it'; 'it-ch' = 'it-it'
            'pt-br' = 'pt-br'; 'pt-pt' = 'pt-pt'
            'ja-jp' = 'ja-jp'; 'ko-kr' = 'ko-kr'
            'zh-cn' = 'zh-cn'; 'zh-tw' = 'zh-tw'; 'zh-hk' = 'zh-tw'; 'zh-sg' = 'zh-cn'
            'nl-nl' = 'nl-nl'; 'nl-be' = 'nl-nl'
            'sv-se' = 'sv-se'; 'da-dk' = 'da-dk'; 'no-no' = 'nb-no'; 'nb-no' = 'nb-no'
            'fi-fi' = 'fi-fi'; 'pl-pl' = 'pl-pl'; 'ru-ru' = 'ru-ru'
            'cs-cz' = 'cs-cz'; 'hu-hu' = 'hu-hu'; 'tr-tr' = 'tr-tr'
            'ar-sa' = 'ar-sa'; 'he-il' = 'he-il'; 'th-th' = 'th-th'
        }
        
        if ($languageMap.ContainsKey($languageTag)) {
            return $languageMap[$languageTag]
        }
        
        # Try just the language part if full locale not found
        $languageOnly = $languageTag.Split('-')[0]
        $fallbackMap = @{
            'en' = 'en-us'; 'de' = 'de-de'; 'fr' = 'fr-fr'; 'es' = 'es-es'
            'it' = 'it-it'; 'pt' = 'pt-br'; 'ja' = 'ja-jp'; 'ko' = 'ko-kr'
            'zh' = 'zh-cn'; 'nl' = 'nl-nl'; 'sv' = 'sv-se'; 'da' = 'da-dk'
            'no' = 'nb-no'; 'fi' = 'fi-fi'; 'pl' = 'pl-pl'; 'ru' = 'ru-ru'
            'cs' = 'cs-cz'; 'hu' = 'hu-hu'; 'tr' = 'tr-tr'
            'ar' = 'ar-sa'; 'he' = 'he-il'; 'th' = 'th-th'
        }
        
        if ($fallbackMap.ContainsKey($languageOnly)) {
            return $fallbackMap[$languageOnly]
        }
        
        Write-WULog "System language '$languageTag' not supported, defaulting to 'en-us'" -Level Warning
        return 'en-us'
    }
    catch {
        Write-WULog "Failed to detect system language: $($_.Exception.Message)" -Level Warning
        return 'en-us'
    }
}

function Invoke-FidoDownloadEnhanced {
    <#
    .SYNOPSIS
        Downloads Windows 11 ISO using the Fido PowerShell script (Enhanced with PS 5.1 compatibility)
    #>

    
    param(
        [string]$OutputPath,
        [string]$Language,
        [string]$Edition,
        [string]$Architecture,
        [switch]$Force
    )
    
    Write-WULog "Starting enhanced Fido download method" -Level Info
    
    # Download Fido script with retry logic
    $fidoPath = Join-Path $OutputPath "Fido.ps1"
    $fidoUrl = "https://github.com/pbatard/Fido/raw/master/Fido.ps1"
    
    $fidoDownloadSuccess = $false
    $fidoRetryCount = 0
    $maxFidoRetries = 3
    
    while ($fidoRetryCount -lt $maxFidoRetries -and -not $fidoDownloadSuccess) {
        $fidoRetryCount++
        
        try {
            Write-WULog "Downloading Fido script (attempt $fidoRetryCount): $fidoUrl" -Level Info
            
            # Use more robust download with progress and timeout
            $webClient = New-Object System.Net.WebClient
            $webClient.DownloadFile($fidoUrl, $fidoPath)
            
            if (Test-Path $fidoPath) {
                $fidoSize = (Get-Item $fidoPath).Length
                if ($fidoSize -gt 1000) {  # Basic size check
                    $fidoDownloadSuccess = $true
                    Write-WULog "Fido script downloaded successfully ($fidoSize bytes)" -Level Info
                } else {
                    throw "Downloaded Fido script appears incomplete"
                }
            } else {
                throw "Fido script file not found after download"
            }
        }
        catch {
            Write-WULog "Fido download attempt $fidoRetryCount failed: $($_.Exception.Message)" -Level Warning
            if ($fidoRetryCount -lt $maxFidoRetries) {
                Start-Sleep -Seconds 5
            }
        }
    }
    
    if (-not $fidoDownloadSuccess) {
        throw "Failed to download Fido script after $maxFidoRetries attempts"
    }
    
    try {
        # Prepare Fido parameters with enhanced mapping
        $editionMap = @{
            'Home' = 'Home'
            'Professional' = 'Pro'
            'Education' = 'Education' 
            'Enterprise' = 'Enterprise'
        }
        
        $fidoEdition = if ($editionMap.ContainsKey($Edition)) { $editionMap[$Edition] } else { 'Pro' }
        
        $fidoParams = @{
            Win = '11'
            Rel = 'Latest'
            Ed = $fidoEdition
            Lang = $Language
            Arch = $Architecture
            GetUrl = $false
        }
        
        Write-WULog "Executing Fido with enhanced parameters: Win=$($fidoParams.Win), Rel=$($fidoParams.Rel), Ed=$($fidoParams.Ed), Lang=$($fidoParams.Lang), Arch=$($fidoParams.Arch)" -Level Info
        
        # Execute Fido script with better error handling
        $previousLocation = Get-Location
        Set-Location $OutputPath
        
        try {
            # Check for existing ISO files before download
            $preExistingISOs = Get-ChildItem -Path $OutputPath -Filter "*.iso" -ErrorAction SilentlyContinue
            
            # Execute Fido with enhanced error capture
            $fidoOutput = & $fidoPath @fidoParams 2>&1
            
            if ($LASTEXITCODE -and $LASTEXITCODE -ne 0) {
                throw "Fido exited with code: $LASTEXITCODE. Output: $fidoOutput"
            }
            
            # Enhanced ISO file detection
            Start-Sleep -Seconds 2  # Allow file system to update
            
            $newIsoFiles = Get-ChildItem -Path $OutputPath -Filter "*.iso" -ErrorAction SilentlyContinue |
                          Where-Object { $_.Name -notlike "*windows10*" -and $_.Name -like "*windows*11*" } |
                          Sort-Object LastWriteTime -Descending
            
            # Filter out pre-existing ISOs
            if ($preExistingISOs) {
                $newIsoFiles = $newIsoFiles | Where-Object { 
                    $newFile = $_
                    -not ($preExistingISOs | Where-Object { $_.Name -eq $newFile.Name })
                }
            }
            
            if ($newIsoFiles) {
                $isoFile = $newIsoFiles[0].FullName
                Write-WULog "Enhanced Fido download completed: $isoFile" -Level Info
                return $isoFile
            } else {
                # Fallback: look for any recent Windows 11 ISO
                $allIsos = Get-ChildItem -Path $OutputPath -Filter "*win*11*.iso" -ErrorAction SilentlyContinue |
                          Sort-Object LastWriteTime -Descending
                
                if ($allIsos) {
                    $isoFile = $allIsos[0].FullName
                    Write-WULog "Found potential Windows 11 ISO: $isoFile" -Level Info
                    return $isoFile
                }
                
                throw "No Windows 11 ISO file found after Fido execution. Output: $fidoOutput"
            }
        }
        finally {
            Set-Location $previousLocation
        }
    }
    catch {
        Write-WULog "Enhanced Fido execution failed: $($_.Exception.Message)" -Level Error
        throw
    }
    finally {
        # Clean up Fido script
        if (Test-Path $fidoPath) {
            try {
                Remove-Item $fidoPath -Force -ErrorAction SilentlyContinue
                Write-WULog "Fido script cleanup completed" -Level Info
            }
            catch {
                Write-WULog "Could not clean up Fido script: $($_.Exception.Message)" -Level Warning
            }
        }
    }
}

function Invoke-UUPDownloadEnhanced {
    <#
    .SYNOPSIS
        Downloads Windows 11 ISO using UUP dump method (Enhanced placeholder)
    #>

    
    param(
        [string]$OutputPath,
        [string]$Language,
        [string]$Edition,
        [string]$Architecture,
        [switch]$Force
    )
    
    Write-WULog "Enhanced UUP download method - currently not implemented" -Level Warning
    throw "UUP download method requires specialized UUP API implementation"
}

function Invoke-MediaCreationToolDownloadEnhanced {
    <#
    .SYNOPSIS
        Downloads Windows 11 ISO using Microsoft's Media Creation Tool (Enhanced)
    #>

    
    param(
        [string]$OutputPath,
        [string]$Language,
        [string]$Edition,
        [string]$Architecture,
        [switch]$Force
    )
    
    Write-WULog "Starting enhanced Media Creation Tool download method" -Level Info
    
    # Download Media Creation Tool with retry logic
    $mctPath = Join-Path $OutputPath "MediaCreationToolW11.exe"
    $mctUrl = "https://go.microsoft.com/fwlink/?linkid=2156295"
    
    $mctDownloadSuccess = $false
    $mctRetryCount = 0
    $maxMctRetries = 3
    
    while ($mctRetryCount -lt $maxMctRetries -and -not $mctDownloadSuccess) {
        $mctRetryCount++
        
        try {
            Write-WULog "Downloading Media Creation Tool (attempt $mctRetryCount): $mctUrl" -Level Info
            
            # Use WebClient for better control and PS 5.1 compatibility
            $webClient = New-Object System.Net.WebClient
            $webClient.DownloadFile($mctUrl, $mctPath)
            
            if (Test-Path $mctPath) {
                $mctSize = (Get-Item $mctPath).Length
                if ($mctSize -gt 1000000) {  # Should be several MB
                    $mctDownloadSuccess = $true
                    Write-WULog "Media Creation Tool downloaded successfully ($([math]::Round($mctSize/1MB, 2)) MB)" -Level Info
                } else {
                    throw "Downloaded Media Creation Tool appears incomplete"
                }
            } else {
                throw "Media Creation Tool file not found after download"
            }
        }
        catch {
            Write-WULog "MCT download attempt $mctRetryCount failed: $($_.Exception.Message)" -Level Warning
            if ($mctRetryCount -lt $maxMctRetries) {
                Start-Sleep -Seconds 10
            }
        }
    }
    
    if (-not $mctDownloadSuccess) {
        throw "Failed to download Media Creation Tool after $maxMctRetries attempts"
    }
    
    try {
        Write-WULog "Media Creation Tool automated execution is complex and may require user interaction" -Level Warning
        Write-WULog "For fully automated ISO download, Fido method is recommended" -Level Info
        
        # Note: MCT typically requires user interaction for ISO creation
        # This is a simplified implementation that downloads the tool
        # In practice, MCT may require GUI interaction for ISO creation
        
        throw "Media Creation Tool requires manual interaction for ISO creation. Use Fido method for automation."
    }
    catch {
        Write-WULog "Enhanced Media Creation Tool execution failed: $($_.Exception.Message)" -Level Error
        throw
    }
    finally {
        # Clean up Media Creation Tool
        if (Test-Path $mctPath) {
            try {
                Remove-Item $mctPath -Force -ErrorAction SilentlyContinue
                Write-WULog "Media Creation Tool cleanup completed" -Level Info
            }
            catch {
                Write-WULog "Could not clean up Media Creation Tool: $($_.Exception.Message)" -Level Warning
            }
        }
    }
}

function Test-ISOFileEnhanced {
    <#
    .SYNOPSIS
        Enhanced verification that a file is a valid Windows 11 ISO file
    #>

    
    param(
        [Parameter(Mandatory)]
        [string]$Path
    )
    
    try {
        if (-not (Test-Path $Path)) {
            Write-WULog "ISO file does not exist: $Path" -Level Error
            return $false
        }
        
        $file = Get-Item $Path
        Write-WULog "Verifying ISO file: $($file.Name) ($([math]::Round($file.Length / 1GB, 2)) GB)" -Level Info
        
        # Enhanced size validation for Windows 11
        if ($file.Length -lt 3.5GB) {
            Write-WULog "ISO file too small for Windows 11: $([math]::Round($file.Length / 1GB, 2)) GB (minimum ~3.5GB)" -Level Warning
            return $false
        }
        
        if ($file.Length -gt 8GB) {
            Write-WULog "ISO file larger than expected: $([math]::Round($file.Length / 1GB, 2)) GB (maximum ~8GB)" -Level Warning
        }
        
        # Enhanced file signature verification
        try {
            $buffer = New-Object byte[] 4096
            $stream = [System.IO.File]::OpenRead($Path)
            $bytesRead = $stream.Read($buffer, 0, 4096)
            $stream.Close()
            
            if ($bytesRead -lt 4096) {
                Write-WULog "Could not read sufficient bytes for verification" -Level Warning
                return $false
            }
            
            # Check for standard ISO signatures
            $hasISOSignature = $false
            
            # Look for "CD001" at various offsets (ISO 9660)
            for ($offset = 32768; $offset -lt 40000; $offset += 2048) {
                if ($offset + 5 -lt $buffer.Length) {
                    $signature = [System.Text.Encoding]::ASCII.GetString($buffer, ($offset % $buffer.Length), 5)
                    if ($signature -eq "CD001") {
                        $hasISOSignature = $true
                        break
                    }
                }
            }
            
            # Alternative check for UDF signatures
            if (-not $hasISOSignature) {
                $udfPatterns = @("BEA01", "NSR02", "NSR03")
                foreach ($pattern in $udfPatterns) {
                    $patternBytes = [System.Text.Encoding]::ASCII.GetBytes($pattern)
                    for ($i = 0; $i -le ($buffer.Length - $patternBytes.Length); $i++) {
                        $match = $true
                        for ($j = 0; $j -lt $patternBytes.Length; $j++) {
                            if ($buffer[$i + $j] -ne $patternBytes[$j]) {
                                $match = $false
                                break
                            }
                        }
                        if ($match) {
                            $hasISOSignature = $true
                            break
                        }
                    }
                    if ($hasISOSignature) { break }
                }
            }
            
            if ($hasISOSignature) {
                Write-WULog "ISO file signature verification passed" -Level Info
            } else {
                Write-WULog "No standard ISO signature found, but file may still be valid" -Level Warning
            }
            
            return $true
        }
        catch {
            Write-WULog "File signature verification failed: $($_.Exception.Message)" -Level Warning
            # Don't fail completely on signature check errors
            return $true
        }
    }
    catch {
        Write-WULog "Enhanced ISO file verification failed: $($_.Exception.Message)" -Level Error
        return $false
    }
}

#endregion Enhanced Helper Functions