scripts/modules/environment/configure-docker-wsl-integration.ps1

# strangeloop Setup - Docker WSL Integration Configuration Module
# Version: 1.0.0


param(
    [switch]$RequiresWSL,
    [switch]${test-only},
    [switch]$Verbose
)

# Import shared modules
$SharedPath = Split-Path $PSScriptRoot -Parent | Join-Path -ChildPath "shared"
Import-Module "$SharedPath\write-functions.ps1" -Force -DisableNameChecking
Import-Module "$SharedPath\test-functions.ps1" -Force -DisableNameChecking

function Set-DockerWSLIntegration {
    <#
    .SYNOPSIS
    Configures Docker Desktop for WSL integration
    
    .DESCRIPTION
    Enables WSL 2 based engine and default WSL distro integration in Docker Desktop settings
    
    .PARAMETER test-only
    Only test the configuration without making changes
    
    .OUTPUTS
    Boolean indicating success
    #>

    param(
        [switch]${test-only}
    )
    
    try {
        Write-Info "Configuring Docker Desktop for WSL integration..."
        
        if (${test-only}) {
            Write-Info "Would configure Docker Desktop WSL integration settings"
            return $true
        }
        
        # Docker Desktop settings are stored in %APPDATA%\Docker\settings.json
        $dockerSettingsPath = Join-Path $env:APPDATA "Docker\settings.json"
        
        if (-not (Test-Path $dockerSettingsPath)) {
            Write-Warning "Docker Desktop settings file not found. Docker may need to be started first."
            Write-Info "WSL integration can be configured manually in Docker Desktop settings:"
            Write-Info " 1. Open Docker Desktop"
            Write-Info " 2. Go to Settings -> General -> 'Use the WSL 2 based engine'"
            Write-Info " 3. Go to Settings -> Resources -> WSL integration -> 'Enable integration with my default WSL distro'"
            
            # Check if Docker Desktop is installed but not running
            $dockerDesktopPath = Get-ChildItem -Path "${env:ProgramFiles}\Docker\Docker\Docker Desktop.exe" -ErrorAction SilentlyContinue
            if ($dockerDesktopPath) {
                Write-Info "Docker Desktop is installed but may not be running. Start Docker Desktop and run this configuration again."
                return $true  # Return true as this is not a failure, just needs manual intervention
            } else {
                Write-Warning "Docker Desktop installation not found"
                return $true  # Still return true as Docker might be installed elsewhere
            }
        }
        
        try {
            # Read current settings
            $settingsContent = Get-Content $dockerSettingsPath -Raw | ConvertFrom-Json
            $settingsModified = $false
            
            # Enable WSL 2 based engine
            if (-not $settingsContent.PSObject.Properties['useWsl2'] -or -not $settingsContent.useWsl2) {
                Write-Info "Enabling WSL 2 based engine..."
                $settingsContent | Add-Member -Name "useWsl2" -Value $true -MemberType NoteProperty -Force
                $settingsModified = $true
            } else {
                Write-Info "WSL 2 based engine already enabled"
            }
            
            # Enable default WSL distro integration
            if (-not $settingsContent.PSObject.Properties['wslEngineEnabled'] -or -not $settingsContent.wslEngineEnabled) {
                Write-Info "Enabling WSL engine integration..."
                $settingsContent | Add-Member -Name "wslEngineEnabled" -Value $true -MemberType NoteProperty -Force
                $settingsModified = $true
            } else {
                Write-Info "WSL engine integration already enabled"
            }
            
            # Ensure WSL distros integration object exists
            if (-not $settingsContent.PSObject.Properties['enableIntegrationWithDefaultWslDistro'] -or -not $settingsContent.enableIntegrationWithDefaultWslDistro) {
                Write-Info "Enabling integration with default WSL distro..."
                $settingsContent | Add-Member -Name "enableIntegrationWithDefaultWslDistro" -Value $true -MemberType NoteProperty -Force
                $settingsModified = $true
            } else {
                Write-Info "Default WSL distro integration already enabled"
            }
            
            # Get current default WSL distro and enable it specifically
            try {
                $defaultDistro = wsl.exe --status 2>$null | Select-String "Default Distribution" | ForEach-Object { 
                    $line = $_.ToString()
                    if ($line -match "Default Distribution:\s*(.+)") {
                        $matches[1].Trim()
                    }
                }
                
                if ($defaultDistro) {
                    Write-Info "Found default WSL distro: $defaultDistro"
                    
                    # Ensure integrationOptions object exists
                    if (-not $settingsContent.PSObject.Properties['integrationOptions']) {
                        $settingsContent | Add-Member -Name "integrationOptions" -Value @{} -MemberType NoteProperty
                    }
                    
                    # Enable the specific distro
                    if (-not $settingsContent.integrationOptions.PSObject.Properties[$defaultDistro] -or -not $settingsContent.integrationOptions.$defaultDistro) {
                        Write-Info "Enabling Docker integration for $defaultDistro..."
                        $settingsContent.integrationOptions | Add-Member -Name $defaultDistro -Value $true -MemberType NoteProperty -Force
                        $settingsModified = $true
                    } else {
                        Write-Info "Docker integration for $defaultDistro already enabled"
                    }
                }
            } catch {
                Write-Warning "Could not determine default WSL distro: $($_.Exception.Message)"
            }
            
            # Save settings if modified
            if ($settingsModified) {
                Write-Progress "Updating Docker Desktop settings..."
                $settingsContent | ConvertTo-Json -Depth 10 | Set-Content $dockerSettingsPath -Encoding UTF8
                Write-Success "Docker Desktop WSL integration settings updated"
                Write-Info "Note: Docker Desktop may need to be restarted for settings to take effect"
                
                # Check if Docker Desktop is running and suggest restart
                $dockerProcess = Get-Process -Name "Docker Desktop" -ErrorAction SilentlyContinue
                if ($dockerProcess) {
                    Write-Warning "Docker Desktop is currently running. Please restart it to apply WSL integration settings:"
                    Write-Info " 1. Right-click Docker Desktop in system tray"
                    Write-Info " 2. Select 'Quit Docker Desktop'"
                    Write-Info " 3. Start Docker Desktop again"
                }
            } else {
                Write-Success "Docker Desktop WSL integration already configured"
            }
            
            return $true
            
        } catch {
            Write-Warning "Failed to update Docker settings file: $($_.Exception.Message)"
            Write-Info "Please configure WSL integration manually in Docker Desktop:"
            Write-Info " 1. Open Docker Desktop"
            Write-Info " 2. Go to Settings -> General -> 'Use the WSL 2 based engine'"
            Write-Info " 3. Go to Settings -> Resources -> WSL integration -> 'Enable integration with my default WSL distro'"
            return $false
        }
        
    } catch {
        Write-Warning "Docker WSL integration configuration failed: $($_.Exception.Message)"
        return $false
    }
}

function Set-DockerWSLIntegrationForProject {
    <#
    .SYNOPSIS
    Main function to configure Docker WSL integration based on project requirements
    
    .PARAMETER RequiresWSL
    Whether the project requires WSL functionality
    
    .PARAMETER test-only
    Only test the configuration without making changes
    
    .OUTPUTS
    Boolean indicating success
    #>

    param(
        [switch]$RequiresWSL,
        [switch]${test-only}
    )
    
    Write-Step "Configuring Docker WSL Integration..."
    
    try {
        if (-not $RequiresWSL) {
            Write-Info "Project does not require WSL - skipping Docker WSL integration"
            return $true
        }
        
        # Check if Docker is installed
        if (-not (Test-Command "docker")) {
            Write-Warning "Docker is not installed - skipping WSL integration configuration"
            return $false
        }
        
        Write-Info "Project requires WSL - configuring Docker WSL integration"
        
        if (${test-only}) {
            Write-Success "Docker WSL integration configuration test completed"
            Write-Info "Would configure Docker Desktop for WSL integration based on project requirements"
            return $true
        }
        
        # Configure WSL integration
        $result = Set-DockerWSLIntegration -test-only:${test-only}
        
        if ($result) {
            Write-Success "Docker WSL integration configuration completed"
            return $true
        } else {
            Write-Warning "Docker WSL integration configuration failed - manual setup may be required"
            Write-Info "Manual setup instructions:"
            Write-Info " 1. Open Docker Desktop"
            Write-Info " 2. Go to Settings -> General -> 'Use the WSL 2 based engine'"
            Write-Info " 3. Go to Settings -> Resources -> WSL integration -> 'Enable integration with my default WSL distro'"
            # Return true since this is not a critical failure that should stop the bootstrap process
            return $true
        }
        
    } catch {
        Write-Error "Docker WSL integration configuration failed: $($_.Exception.Message)"
        return $false
    }
}

# Main execution
if ($MyInvocation.InvocationName -ne '.') {
    $result = Set-DockerWSLIntegrationForProject -RequiresWSL:$RequiresWSL -test-only:${test-only}
    
    if ($result) {
        Write-Success "Docker WSL integration configuration completed successfully"
        return @{ Success = $true; Phase = "Docker WSL Integration"; Message = "Docker WSL integration configured successfully" }
    } else {
        Write-Warning "Docker WSL integration configuration needs manual setup"
        # Return success since this is not a critical failure
        return @{ Success = $true; Phase = "Docker WSL Integration"; Message = "Docker WSL integration requires manual configuration" }
    }
}

# Export functions for module usage
if ($MyInvocation.MyCommand.ModuleName) {
    Export-ModuleMember -Function @(
        'Set-DockerWSLIntegrationForProject',
        'Set-DockerWSLIntegration'
    )
}