functions/_Resolve-GistMapConfig.ps1

# <copyright file="_Resolve-GistMapConfig.ps1" company="Endjin Limited">
# Copyright (c) Endjin Limited. All rights reserved.
# </copyright>

<#
.SYNOPSIS
    Internal helper that resolves the effective gist-map configuration from the supplied parameters.

.DESCRIPTION
    This private function centralises the logic for deciding which gist-map source to use:
    1. A local file path (GistMapPath), returned directly without any network access.
    2. An HTTP URL passed via the GistMapUrl parameter or set via the module default $script:GistMapUrl)
    3. A GitHub repository override passed via the GistMapRepo parameter or set via the module default
       $script:DefaultGistMapGitSource, from which a vendir git source is constructed and then passed
       to _Get-GistMapData. This is the default mechanism when GistMapPath and GistMapUrl are not
       specified.

    The function always returns a PSCustomObject with three properties:
      - GistMap : the parsed gist-map hashtable, or $null on failure
      - EffectiveUrl : the HTTP URL (only when GistMapPath is supplied)
      - EffectiveGitSource : the vendir git source hashtable used

.PARAMETER GistMapPath
    The path to a local gist-map YAML file. When specified, remote fetching is skipped.

.PARAMETER GistMapUrl
    The HTTP URL to fetch the gist-map from. Used when GistMapRepo is not specified.

.PARAMETER GistMapRepo
    A GitHub repository in 'owner/repo' format. When specified, overrides GistMapUrl and
    constructs both an HTTP URL and a vendir git source from GistMapRepo, GistMapRepoRef, and
    GistMapRepoPath.

.PARAMETER GistMapRepoRef
    The git ref to use with GistMapRepo. Defaults to 'main'.

.PARAMETER GistMapRepoPath
    The file path within the GistMapRepo repository to the gist-map file. Defaults to
     'module/gist-map.yml' via the module-scoped variable 'DefaultGistMapUrl'.

.PARAMETER NoCache
    When specified, bypasses the gist-map cache and forces a fresh read.

.EXAMPLE
    _Resolve-GistMapConfig -GistMapPath './my-gist-map.yml'

.EXAMPLE
    _Resolve-GistMapConfig -GistMapRepo 'myorg/my-gists' -GistMapRepoRef 'v2.0'

.EXAMPLE
    _Resolve-GistMapConfig -GistMapUrl $script:DefaultGistMapUrl -NoCache

.NOTES
    This is a private helper function (prefixed with '_') and is not exported from the module.
#>

function _Resolve-GistMapConfig {
    [CmdletBinding(DefaultParameterSetName='ByRepo')]
    param (
        [Parameter(ParameterSetName='ByPath', Mandatory)]
        [string] $GistMapPath,

        [Parameter(ParameterSetName='ByUrl', Mandatory)]
        [string] $GistMapUrl,

        [Parameter(ParameterSetName='ByRepo')]
        [string] $GistMapRepo,

        [Parameter(ParameterSetName='ByRepo')]
        [string] $GistMapRepoRef,

        [Parameter(ParameterSetName='ByRepo')]
        [string] $GistMapRepoPath,

        [Parameter()]
        [switch] $NoCache
    )

    process {
        Set-StrictMode -Version Latest

        if ($GistMapPath) {
            # Handle scenario when using a local gist-map file
            if (-not (Test-Path $GistMapPath -PathType Leaf)) {
                throw "GistMapPath '$GistMapPath' does not exist."
            }
            $gistMap = Get-Content -Path $GistMapPath -Raw | ConvertFrom-Yaml
            return [PSCustomObject]@{
                GistMap            = $gistMap
                EffectiveUrl       = $null
                EffectiveGitSource = $null
            }
        }
        elseif ($GistMapUrl) {
            # Handle scenario when using a gist-map file from a public GitHub repo (i.e. available via anonymous HTTP)
            $effectiveUrl = $GistMapUrl
            $effectiveGitSource = $script:DefaultGistMapGitSource
        }
        elseif ($PSCmdlet.ParameterSetName -eq 'ByRepo') {
            # Handle scenario when using a gist-map file from a GitHub repo, assuming module defaults for parameters not explicitly passed
            $effectiveRepo = $GistMapRepo ? $GistMapRepo : $script:DefaultGistMapGitSource.repo
            $effectiveGitSource = @{
                repo = $effectiveRepo
                url = "https://github.com/$effectiveRepo.git"
                ref = $GistMapRepoRef ? $GistMapRepoRef : $script:DefaultGistMapGitSource.ref
                path = $GistMapRepoPath ? $GistMapRepoPath : $script:DefaultGistMapGitSource.path
            }
            $effectiveUrl = $null
        }

        # Resolve the path here to ensure the ScriptRoot portion of the cache key is consistent
        # with other scenarios (e.g. the tab completers)
        $scriptRoot = (Resolve-Path (Join-Path $PSScriptRoot '..')).Path
        $gistMap = _Get-GistMapData -ScriptRoot $scriptRoot `
                                    -GistMapUrl $effectiveUrl `
                                    -GistMapGitSource $effectiveGitSource `
                                    -NoCache:$NoCache

        return [PSCustomObject]@{
            GistMap            = $gistMap
            EffectiveUrl       = $effectiveUrl
            EffectiveGitSource = $effectiveGitSource
        }
    }
}