Private/Utilities/Test-PIMDependencies.ps1

function Test-PIMDependencies {
    <#
    .SYNOPSIS
        Comprehensive dependency check for PIM Activation module.
     
    .DESCRIPTION
        Performs a complete analysis of module dependencies, version compatibility,
        and system requirements for optimal PIM Activation functionality.
     
    .EXAMPLE
        Test-PIMDependencies
        Runs a full dependency check and reports status.
         
    .EXAMPLE
        Test-PIMDependencies -Detailed
        Provides detailed information about each dependency.
     
    .OUTPUTS
        PSCustomObject with dependency status and recommendations
    #>

    [CmdletBinding()]
    param(
        [Parameter()]
        [switch]$Detailed
    )
    
    $result = [PSCustomObject]@{
        OverallStatus = 'Unknown'
        PowerShellVersion = [PSCustomObject]@{
            Current = $PSVersionTable.PSVersion
            Required = [version]'7.0'
            Compatible = $false
        }
        ModuleStatus = [System.Collections.ArrayList]::new()
        Conflicts = [System.Collections.ArrayList]::new()
        Recommendations = [System.Collections.ArrayList]::new()
        ReadyForActivation = $false
    }
    
    # Check PowerShell version
    $result.PowerShellVersion.Compatible = $PSVersionTable.PSVersion -ge [version]'7.0'
    
    if (-not $result.PowerShellVersion.Compatible) {
        $null = $result.Recommendations.Add("Upgrade to PowerShell 7.0 or later from https://aka.ms/powershell")
    }
    
    # Check required modules using our version requirements with suppressed verbose output
    $originalVerbosePreference = $VerbosePreference
    $VerbosePreference = 'SilentlyContinue'
    
    if (Get-Variable -Name 'script:RequiredModuleVersions' -Scope Script -ErrorAction SilentlyContinue) {
        $requiredVersions = $script:RequiredModuleVersions
    }
    else {
        # Fallback if called outside module context
        $requiredVersions = @{
            'Microsoft.Graph.Authentication' = '2.29.0'
            'Microsoft.Graph.Users' = '2.29.0'
            'Microsoft.Graph.Identity.DirectoryManagement' = '2.29.0'
            'Microsoft.Graph.Identity.Governance' = '2.29.0'
            'Microsoft.Graph.Groups' = '2.29.0'
            'Microsoft.Graph.Identity.SignIns' = '2.29.0'
            'Az.Accounts' = '5.1.0'
        }
    }
    
    foreach ($moduleName in $requiredVersions.Keys) {
        $requiredVersion = [version]$requiredVersions[$moduleName]
        $loadedModule = Get-Module -Name $moduleName -ErrorAction SilentlyContinue
        $availableModules = Get-Module -ListAvailable -Name $moduleName -ErrorAction SilentlyContinue
        
        $moduleStatus = [PSCustomObject]@{
            Name = $moduleName
            RequiredVersion = $requiredVersion
            LoadedVersion = if ($loadedModule) { $loadedModule.Version } else { $null }
            AvailableVersions = if ($availableModules) { $availableModules.Version | Sort-Object -Descending } else { @() }
            Status = 'Unknown'
            Loaded = [bool]$loadedModule
            Available = [bool]$availableModules
            VersionConflict = $false
        }
        
        # Determine status
        if ($loadedModule) {
            if ($loadedModule.Version -ge $requiredVersion) {
                $moduleStatus.Status = 'Loaded-Compatible'
            }
            else {
                $moduleStatus.Status = 'Loaded-Incompatible'
                $moduleStatus.VersionConflict = $true
                $null = $result.Conflicts.Add("$moduleName v$($loadedModule.Version) is loaded but v$requiredVersion+ is required")
            }
        }
        elseif ($availableModules) {
            $suitableVersions = $availableModules | Where-Object { $_.Version -ge $requiredVersion }
            if ($suitableVersions) {
                $moduleStatus.Status = 'Available-Compatible'
            }
            else {
                $moduleStatus.Status = 'Available-Incompatible'
                $null = $result.Recommendations.Add("Update $moduleName to version $requiredVersion or later")
            }
        }
        else {
            $moduleStatus.Status = 'Not-Available'
            $null = $result.Recommendations.Add("Install $moduleName version $requiredVersion or later")
        }
        
        $null = $result.ModuleStatus.Add($moduleStatus)
    }
    
    # Restore original verbose preference
    $VerbosePreference = $originalVerbosePreference
    
    # Determine overall status
    $incompatibleLoaded = $result.ModuleStatus | Where-Object { $_.Status -eq 'Loaded-Incompatible' }
    $notAvailable = $result.ModuleStatus | Where-Object { $_.Status -eq 'Not-Available' }
    $availableIncompatible = $result.ModuleStatus | Where-Object { $_.Status -eq 'Available-Incompatible' }
    
    if ($incompatibleLoaded) {
        $result.OverallStatus = 'Version-Conflicts'
        $null = $result.Recommendations.Add("Run 'Clear-ModuleVersionConflicts' to resolve version conflicts")
        $null = $result.Recommendations.Add("Restart PowerShell session after clearing conflicts")
    }
    elseif ($notAvailable -or $availableIncompatible) {
        $result.OverallStatus = 'Missing-Dependencies'
        $null = $result.Recommendations.Add("Run 'Install-RequiredModules' to install missing dependencies")
    }
    else {
        $result.OverallStatus = 'Ready'
        $result.ReadyForActivation = $true
    }
    
    # Display results only if detailed or if there are issues
    if ($Detailed -or (-not $result.ReadyForActivation)) {
        Write-Host "`n=== PIM Activation Dependency Check ===" -ForegroundColor Cyan
        Write-Host "PowerShell Version: $($result.PowerShellVersion.Current) " -NoNewline
        if ($result.PowerShellVersion.Compatible) {
            Write-Host "✓" -ForegroundColor Green
        }
        else {
            Write-Host "❌ (Requires 7.0+)" -ForegroundColor Red
        }
        
        Write-Host "`nModule Dependencies:" -ForegroundColor Cyan
        foreach ($module in $result.ModuleStatus) {
            $icon = switch ($module.Status) {
                'Loaded-Compatible' { '✓' }
                'Available-Compatible' { '⚡' }
                'Loaded-Incompatible' { '❌' }
                'Available-Incompatible' { '⚠️' }
                'Not-Available' { '❌' }
                default { '❓' }
            }
            
            $color = switch ($module.Status) {
                'Loaded-Compatible' { 'Green' }
                'Available-Compatible' { 'Yellow' }
                'Loaded-Incompatible' { 'Red' }
                'Available-Incompatible' { 'Red' }
                'Not-Available' { 'Red' }
                default { 'Gray' }
            }
            
            Write-Host " $icon " -ForegroundColor $color -NoNewline
            Write-Host "$($module.Name) " -NoNewline
            
            if ($module.LoadedVersion) {
                Write-Host "v$($module.LoadedVersion) (loaded)" -ForegroundColor $color
            }
            elseif ($module.AvailableVersions) {
                Write-Host "v$($module.AvailableVersions[0]) (available)" -ForegroundColor $color
            }
            else {
                Write-Host "(not installed)" -ForegroundColor $color
            }
            
            if ($Detailed -and $module.AvailableVersions.Count -gt 1) {
                Write-Host " Available versions: $($module.AvailableVersions -join ', ')" -ForegroundColor Gray
            }
        }
        
        Write-Host "`nOverall Status: " -NoNewline
        switch ($result.OverallStatus) {
            'Ready' { Write-Host "Ready for PIM Activation ✓" -ForegroundColor Green }
            'Version-Conflicts' { Write-Host "Version Conflicts Detected ❌" -ForegroundColor Red }
            'Missing-Dependencies' { Write-Host "Missing Dependencies ⚠️" -ForegroundColor Yellow }
            default { Write-Host $result.OverallStatus -ForegroundColor Gray }
        }
        
        if ($result.Conflicts.Count -gt 0) {
            Write-Host "`nConflicts:" -ForegroundColor Red
            foreach ($conflict in $result.Conflicts) {
                Write-Host " ❌ $conflict" -ForegroundColor Red
            }
        }
        
        if ($result.Recommendations.Count -gt 0) {
            Write-Host "`nRecommendations:" -ForegroundColor Cyan
            foreach ($recommendation in $result.Recommendations) {
                Write-Host " • $recommendation" -ForegroundColor White
            }
        }
        
        Write-Host ""
    }
    else {
        # Silent mode - only log to verbose
        Write-Verbose "Dependency check completed. Status: $($result.OverallStatus), Ready: $($result.ReadyForActivation)"
    }
    return $result
}