Private/_IndexKritPrimitives.ps1

function _KriticalLensIndexPrimitives {
    <#
    .SYNOPSIS
        Walks every .psm1 in a directory, indexes functions marked with a
        `# COVERS-DSC-RESOURCE: <ResourceName>` comment. Returns a
        hashtable keyed by ResourceName, valued by best New/Get candidate.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$ModuleDir,
        [string]$ModuleFilter = 'Kritical-M365*.psm1',
        [Parameter(Mandatory)][string]$FunctionPrefix,
        [string]$SupersetHint
    )

    if (-not (Test-Path -LiteralPath $ModuleDir)) {
        throw "Module directory does not exist: $ModuleDir"
    }

    $candidatesByResource = @{}
    $modules = Get-ChildItem -Path $ModuleDir -Filter $ModuleFilter -File |
        Where-Object { $_.Name -notmatch '\.bak\.' }

    foreach ($mod in $modules) {
        $body = Get-Content -LiteralPath $mod.FullName -Raw
        $tokens = $null; $errs = $null
        $ast = [System.Management.Automation.Language.Parser]::ParseFile(
            $mod.FullName, [ref]$tokens, [ref]$errs)
        if ($errs -and $errs.Count -gt 0) {
            Write-Warning ("Kritical.Lens: parse errors in {0} — skipping ({1} errors)" -f $mod.Name, $errs.Count)
            continue
        }
        $fnAsts = $ast.FindAll(
            { param($n) $n -is [System.Management.Automation.Language.FunctionDefinitionAst] },
            $true)

        $markerRegex = [regex]'(?m)^\s*#\s*COVERS-DSC-RESOURCE:\s*(?<res>[A-Za-z0-9]+)'
        $lines = $body -split "`n"

        for ($i = 0; $i -lt $lines.Count; $i++) {
            $m = $markerRegex.Match($lines[$i])
            if (-not $m.Success) { continue }
            $resName = $m.Groups['res'].Value

            for ($j = $i + 1; $j -lt [Math]::Min($i + 20, $lines.Count); $j++) {
                if ($lines[$j] -match ('^\s*function\s+(?<fn>(New|Get)-{0}[A-Za-z0-9_]+)' -f [regex]::Escape($FunctionPrefix))) {
                    $fnName = $matches['fn']
                    $fnAst = $fnAsts | Where-Object { $_.Name -eq $fnName } | Select-Object -First 1
                    if (-not $candidatesByResource.ContainsKey($resName)) {
                        $candidatesByResource[$resName] = @{ New = @(); Get = @() }
                    }
                    $paramCount = if ($fnAst -and $fnAst.Body.ParamBlock) {
                        $fnAst.Body.ParamBlock.Parameters.Count
                    } else { 0 }
                    $entry = [pscustomobject]@{
                        Module     = $mod.BaseName
                        FnName     = $fnName
                        FnAst      = $fnAst
                        ParamCount = $paramCount
                    }
                    if ($fnName -like 'New-*') {
                        $candidatesByResource[$resName].New += $entry
                    } elseif ($fnName -like 'Get-*') {
                        $candidatesByResource[$resName].Get += $entry
                    }
                    break
                }
            }
        }
    }

    # Flatten: prefer any function whose name contains the SupersetHint
    # (guaranteed 100% schema-derived). Fall back to the highest
    # parameter-count handcraft otherwise.
    $result = @{}
    foreach ($resName in $candidatesByResource.Keys) {
        $cands = $candidatesByResource[$resName]

        $bestNew = $null
        if ($SupersetHint) {
            $bestNew = $cands.New | Where-Object { $_.FnName -like ("*$SupersetHint*") } | Select-Object -First 1
        }
        if (-not $bestNew) {
            $bestNew = $cands.New | Sort-Object -Property ParamCount -Descending | Select-Object -First 1
        }

        $bestGet = $null
        if ($SupersetHint) {
            $bestGet = $cands.Get | Where-Object { $_.FnName -like ("*$SupersetHint*") } | Select-Object -First 1
        }
        if (-not $bestGet) {
            $bestGet = $cands.Get | Sort-Object -Property ParamCount -Descending | Select-Object -First 1
        }

        $result[$resName] = [pscustomobject]@{
            Module   = if ($bestNew) { $bestNew.Module } elseif ($bestGet) { $bestGet.Module } else { '' }
            NewFn    = if ($bestNew) { $bestNew.FnName } else { $null }
            NewFnAst = if ($bestNew) { $bestNew.FnAst  } else { $null }
            GetFn    = if ($bestGet) { $bestGet.FnName } else { $null }
            GetFnAst = if ($bestGet) { $bestGet.FnAst  } else { $null }
        }
    }
    return $result
}