Private/Comparison/Compare-ByMatcher.ps1

function Compare-ByMatcher {
    <#
    .SYNOPSIS
    Compares baseline policies with assigned policies using specified matching strategy.
     
    .DESCRIPTION
    Orchestrates the comparison between baseline and assigned policies.
    Identifies missing policies, extra policies, and version mismatches.
    Supports both ID-based and name-based matching strategies.
     
    This is the main comparison function that coordinates the three find operations.
     
    .PARAMETER Baseline
    Array of baseline policy objects.
     
    .PARAMETER AssignedPolicies
    Array of assigned policy objects from expanded initiatives.
     
    .PARAMETER BaselineIndex
    PSCustomObject with .ById, .ByName, and .ByNormName hashtables for fast lookup.
     
    .PARAMETER AssignmentIndex
    Hashtable for fast lookup of assigned policies (either ById or ByNormName).
     
    .PARAMETER MatchByNameOnly
    If true, matches by normalized name only. If false, matches by ID first, then name.
     
    .EXAMPLE
    $comparisonResult = Compare-ByMatcher -Baseline $baseline `
                                          -AssignedPolicies $assRefs `
                                          -BaselineIndex $baselineIndex `
                                          -AssignmentIndex $assIndexByNorm `
                                          -MatchByNameOnly $true
     
    Returns PSCustomObject with .Missing, .Extra, and .VersionDiffs arrays.
     
    .OUTPUTS
    PSCustomObject with three properties:
    - Missing: Array of baseline policies not assigned
    - Extra: Array of assigned policies not in baseline
    - VersionDiffs: Array of policies with version mismatches
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [object[]]$Baseline,
        
        [Parameter(Mandatory)]
        [object[]]$AssignedPolicies,
        
        [Parameter(Mandatory)]
        [object]$BaselineIndex,
        
        [Parameter(Mandatory)]
        [hashtable]$AssignmentIndex,
        
        [Parameter()]
        [bool]$MatchByNameOnly = $false
    )
    
    Write-Debug "Starting comparison: Baseline=$($Baseline.Count), Assigned=$($AssignedPolicies.Count), MatchByName=$MatchByNameOnly"
    
    # Find missing policies (in baseline but not assigned)
    $missing = Find-MissingPolicies -Baseline $Baseline `
                                    -AssignmentIndex $AssignmentIndex `
                                    -MatchByNameOnly $MatchByNameOnly
    
    # Find extra policies (assigned but not in baseline)
    $extra = if ($MatchByNameOnly) {
        Find-ExtraPolicies -AssignedPolicies $AssignedPolicies `
                           -BaselineIndex $BaselineIndex.ByNormName `
                           -MatchByNameOnly $MatchByNameOnly
    } else {
        Find-ExtraPolicies -AssignedPolicies $AssignedPolicies `
                           -BaselineIndex $BaselineIndex.ById `
                           -MatchByNameOnly $MatchByNameOnly
    }
    
    # Find version mismatches
    $versionDiffs = Find-VersionMismatches -AssignedPolicies $AssignedPolicies `
                                           -BaselineIndex $BaselineIndex `
                                           -MatchByNameOnly $MatchByNameOnly
    
    Write-Debug "Comparison complete: Missing=$($missing.Count), Extra=$($extra.Count), VersionDiffs=$($versionDiffs.Count)"
    
    return [PSCustomObject]@{
        Missing      = $missing
        Extra        = $extra
        VersionDiffs = $versionDiffs
    }
}