src/Resolve-CachedPackage.ps1

function Resolve-CachedPackage {
    param(
        [Parameter(Mandatory)]
        $Bootstrapper,

        [Parameter(Mandatory)]
        [ValidateSet("Object","Install","File")]
        [string] $From,
        [Parameter(Mandatory)]
        $Options
    )

    switch( $From ){
        "Object" {}
        "Install" {

            # Check desired version against PackageManagement's local cache
            # Check desired version against NuGet (both stable and prerelease)
            
            # **Fallback** to internal local cache.
            <#
                **Reasoning:
 
                PackageManagement is to be prioritized. The purpose of this module is not to reproduce the efforts of PackageManagement
                - Import-Package's purpose is to patch in features that you would expect PackageManagement (PM) to include.
                 
                One such feature is that at this time, PM's Install-Package doesn't support SemVer 2 while NuGet's Install-Package does.
                So, any package not installable by PM will be installed by Import-Package to an internal cache directory.
                - The reason for not using NuGet's Install-Package is that NuGet may or may not be installed on the target system.
 
                Additionally, any package imported using the -Path parameter will be cached here.
 
                The Import-Package module is also designed in such a way that if PM were to update from SemVer 1 to SemVer 2,
                PM packages will still be prioritized. In the long run, this will help reduce Import-Package's file bloat.
            #>

            
            $versions = @{}
            $versions.wanted = $Options.Version
            $versions.pm = @{}

            # Check for a locally installed version from PackageManagement (pm)
            # Also, cache the pm package in memory for faster loading, if it is available
            $pm_package = Get-Package $Options.Name -RequiredVersion (& {
                # Scripting the -RequiredVersion parameter is more performant than several calls to Get-Package
                If( [string]::IsNullOrWhiteSpace( $versions.wanted ) ){
                    $null
                } Else {
                    $versions.wanted.ToString()
                }
            }) -ProviderName NuGet -ErrorAction SilentlyContinue

            $versions.pm.local = $pm_package.Version

            If( -not $Options.Offline ){
                # Check for the upstream version (from NuGet)

                If( $Options.Stable ){
                    $versions.pm.upstream = Try {
                        $Bootstrapper.GetStable( $Options.Name, $versions.wanted )
                    } Catch {}
                }
                
                # If Options.Stable was false or an upstream stable version could not be found, try for a prerelease version
                If( [string]::IsNullOrWhiteSpace( "$( $versions.pm.upstream )" ) ){
                    $versions.pm.upstream = Try {
                        $Bootstrapper.GetPreRelease( $Options.Name, $versions.wanted )
                    } Catch {}

                    # If a prerelease was selected ensure $Options.Stable gets forced to false
                    If( -not [string]::IsNullOrWhiteSpace( "$( $versions.pm.upstream )" ) ){
                        $Options.Stable = $false
                    }
                }
            }

            $versions.cached = @{}; & {
                $root = $Options.CachePath

                # Get all cached packages with the same name
                $candidate_packages = Try {
                    Join-Path $root "*" | Resolve-Path | Split-Path -Leaf | Where-Object {
                        $ending_tokens = "$_".Replace( $Options.Name, "" ) -replace "^\.",""
                        $first_token = ($ending_tokens -split "\.")[0]
                        Try{
                            $null = [int]$first_token
                            $true
                        } Catch {
                            $false
                        }
                    }
                } Catch { $null }

                If( $candidate_packages ){

                    # Get all versions in the directory
                    $candidate_versions = $candidate_packages | ForEach-Object {
                        # Exact replace (.Replace()) followed by regex-replace (-replace)
                        $out = "$_".Replace( $Options.Name, "" ) -replace "^\.",""
                        If( $out -eq $versions.wanted ){
                            $versions.cached.local = $out
                        }
                        $out
                    }
    
                    $candidate_versions = [string[]] $candidate_versions

                    [Array]::Sort[string]( $candidate_versions, [System.Comparison[string]]({
                        param($x, $y)
                        $x = $Bootstrapper.ParseSemVer( $x )
                        $y = $Bootstrapper.ParseSemVer( $y )
    
                        $Bootstrapper.CompareSemVers( $x, $y )
                    }))

                    If( -not $versions.cached.local ){
                        $versions.cached.local = $candidate_versions | Select-Object -Last 1
                    }
    
                    If(@(
                        $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent,
                        ($VerbosePreference -ne 'SilentlyContinue')
                    ) -contains $true ){
                        Write-Host
                        Write-Verbose "[Import-Packge:Preparation] Detected cached packages for $( $Options.Name ) for versions:"
                        $candidate_versions | ForEach-Object {
                            If( $_ -eq $versions.cached.local ){
                                Write-Host ">" $_ -ForegroundColor Green
                            } Else {
                                Write-Host "-" $_
                            }
                        }
                        Write-Host
                        Write-Host "> = either latest or selected version in cache" -ForegroundColor Green
                        Write-Host
                    }
                }
            }

            # At this point we have checked both the PM and Cached Packages for the desired version
            # We have also selected the latest from each in the case that the desired version was not found

            $no_local = -not (& {
                $versions.pm.local -or $versions.cached.local
            })
            $no_upstream = -not (& {
                $versions.pm.upstream
            })

            $versions.best = @{}
            If( -not $no_local ){
                $versions.best.local = & {
                    If( $versions.wanted ){
                        switch( $versions.wanted ){
                            $versions.pm.local { "pm"; break; }
                            $versions.cached.local { "cached" }
                        }
                    } Elseif( $versions.pm.local ){
                        "pm"
                    } Elseif( $versions.cached.local ){
                        "cached"
                    }
                }
            }
            If( -not $no_upstream ){
                $versions.best.upstream = & {
                    "pm"
                }
            }
            
            $install_condition = -not( $no_upstream ) -and (& {
                $no_local -or (& {
                    $best_upstream = $versions[ $versions.best.upstream ].upstream
                    $best_local = $versions[ $versions.best.local ].local

                    $best_upstream -ne $best_local
                })
            })

            If(@(
                $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent,
                ($VerbosePreference -ne 'SilentlyContinue')
            ) -contains $true ){
                Write-Host
                Write-Verbose "[Import-Packge:Preparation] Version control data for $( $Options.Name ):"

                Write-Host "Wanted version:" $versions.wanted -ForegroundColor (& {
                    If( $versions.wanted ){
                        "Green"
                    } Else {
                        "DarkGray"
                    }
                })
                Write-Host
                Write-Host "No upstream:" $no_upstream -ForegroundColor Cyan "(if -offline is used, this should be True)"
                Write-Host "No local:" $no_local -ForegroundColor Cyan
                Write-Host
                Write-Host "Best local source:" $versions.best.local
                Write-Host "Best upstream source:" $versions.best.upstream
                Write-Host
                Write-Host "Cached version:" $versions.cached.local -ForegroundColor (& {
                    If( $versions.best.local -eq "cached" ){
                        "Green"
                    } Else {
                        "DarkGray"
                    }
                })
                Write-Host "PM version:" $versions.pm.local -ForegroundColor (& {
                    If( $versions.best.local -eq "pm" ){
                        "Green"
                    } Else {
                        "DarkGray"
                    }
                })
                Write-Host "Upstream version:" $versions.pm.upstream -ForegroundColor (& {
                    If( $no_upstream ){
                        "DarkGray"
                    } Else {
                        "Magenta"
                    }
                })
                Write-Host
                Write-Host "Attempt Install?" $install_condition -ForegroundColor (& {
                    If( $install_condition ){
                        "Red"
                    } Else {
                        "White"
                    }
                })
                Write-Host
            }

            $Options.Source = If( $install_condition ){
                If( $Options.Stable ){
                    Write-Verbose "[Import-Package:Preparation] Installing $( $Options.Name ) $( $versions[ $versions.best.upstream ].upstream ) via PackageManagement"
                    Try {
                        Install-Package $Options.Name `
                            -ProviderName NuGet `
                            -RequiredVersion $versions[ $versions.best.upstream ].upstream `
                            -SkipDependencies `
                            -Force `
                            -ErrorAction Stop | Out-Null
                    } Catch {
                        Install-Package $Options.Name `
                            -ProviderName NuGet `
                            -RequiredVersion $versions[ $versions.best.upstream ].upstream `
                            -SkipDependencies `
                            -Scope CurrentUser `
                            -Force | Out-Null
                    }

                    # Error check it and return it:
                    $pm_package = Get-Package $Options.Name -RequiredVersion $versions[ $versions.best.upstream ].upstream -ProviderName NuGet -ErrorAction Stop
                    If( $pm_package ){
                        $Options.Installed = $true
                        $Options.Version = $versions[ $versions.best.upstream ].upstream
                        Write-Verbose "[Import-Package:Preparation] Source for $( $Options.Name ) $( $Options.Version ) set to PackageManagement cache"

                        $pm_package.Source
                    } Else {
                        throw "[Import-Package:Preparation] Autoinstall of $( $Options.Name ) $( $versions[ $versions.best.upstream ].upstream ) failed."
                    }
                } Else {
                    $Options.Version = $versions[ $versions.best.upstream ].upstream
                    Write-Verbose "[Import-Package:Preparation] Source for $( $Options.Name ) $( $Options.Version ) set to Import-Package cache"

                    $package_name = "$( $Options.Name ).$( $Options.Version )"
                    
                    $output_path = Join-Path $Options.CachePath "$package_name" "$package_name.nupkg"

                    Try{
                        Resolve-Path $output_path -ErrorAction Stop
                    } Catch {
                        $resource = $bootstrapper.APIs.resources| Where-Object {
                            $_."@type" -eq "PackageBaseAddress/3.0.0"
                        }
                        $id = $resource."@id"

                        $url = @(
                            $id,
                            $Options.Name, "/",
                            $Options.Version, "/",
                            $package_name, ".nupkg"
                        ) -join ""

                        If(@(
                            $PSCmdlet.MyInvocation.BoundParameters["Verbose"].IsPresent,
                            ($VerbosePreference -ne 'SilentlyContinue')
                        ) -contains $true ){
                            Write-Verbose "[Import-Package:Preparation] Installing $( $Options.Name ) $( $Options.Version ) from:"
                            Write-Host "-" $url -ForegroundColor Cyan
                            Write-Host
                        }

                        New-Item (Split-Path $output_path) -Force -ItemType Directory | Out-Null
                        Invoke-WebRequest -Uri $url -OutFile $output_path -ErrorAction Stop | Out-Null
                        [System.IO.Compression.ZipFile]::ExtractToDirectory( $output_path, (Split-Path $output_path), $true ) | Out-Null

                        $Options.Installed = $true

                        $output_path
                    }
                }
            } Elseif( -not( $no_local ) ){
                $Options.Version = $versions[ $versions.best.local ].local

                If( $versions.best.local -eq "cached" ){
                    Write-Verbose "[Import-Package:Preparation] Source for $( $Options.Name ) $( $Options.Version ) set to Import-Package cache"
                    $package_name = "$( $Options.Name ).$( $Options.Version )"
                    Join-Path $Options.CachePath "$package_name" "$package_name.nupkg"
                } Else {
                    Write-Verbose "[Import-Package:Preparation] Source for $( $Options.Name ) $( $Options.Version ) set to PackageManagement cache"
                    $pm_package.Source
                }
            } Else {
                throw "[Import-Package:Preparation] Could not retrieve any packages for $( $Options.Name )"
            }
        }
        "File" {
            $Options.Unmanaged = $true
            $Options.Offline = $true

            # This needs to be corrected by the .nuspec, if it is specified in the nuspec
            # Additionally, if the version is specifed in the .nuspec, it needs to be provided here
            $Options.Name = (Split-Path $Options.Source -LeafBase)

            $cache = Join-Path $Options.CachePath $Options.Name

            # Unpack the package to the cache directory
            If( -not( Test-Path $cache ) ){
                [System.IO.Compression.ZipFile]::ExtractToDirectory( $Options.Source.ToString(), $cache.ToString() )
            }

            $cache_nupkg = Join-Path $cache (Split-Path $Options.Source -Leaf)

            # Copy the nupkg to the cache directory as well
            If( -not( Test-Path $cache_nupkg ) ){
                Copy-Item -Path $Options.Source.ToString() -Destination $cache -Force
            }

            $Options.Source = $cache_nupkg.ToString()
        }
    }

    $Options.Fullname = $Options.Source | Split-Path -LeafBase

    $base_natives_path = If( [string]::IsNullOrWhiteSpace( $Options.NativePath ) ){
        & {
            <#
                (WIP - #49) I'm thinking that this is where we should check to see if the currently processed dependency already has a Natives Folder
                - Then instead of generating a new NativePath, we copy the Natives from this pre-existing folder to the parent.
                - Obviously don't do this in this If block
                - This If block should only run for the base of the dependency tree, if the user did not specify their own nativepath
            #>

            $parent = & {
                Join-Path ($CachePath | Split-Path -Parent) "Natives"
            }
            Join-Path $parent $Options.FullName
        }
    } Else {
        $Options.NativePath
    }
    $this_natives_path = & {
        Join-Path ($base_natives_path | Split-Path -Parent) $Options.Fullname
    }

    If( $this_natives_path -ne $base_natives_path ){
        If( Test-Path $this_natives_path ){
            Write-Verbose "[Import-Package:Preparation] Native files for $( $Options.Name ) $( $Options.Version ) will be copied from cache now:"
            Write-Verbose "- Folder: $this_natives_path"
            Resolve-Path (Join-Path $this_natives_path "*") -ErrorAction SilentlyContinue | ForEach-Object {
                $native = $_
                $native_name = $_ | Split-Path -Leaf
                If( Test-Path (Join-Path $base_natives_path $native_name) ){
                    Write-Verbose "$native_name is already present and loaded. Native dll not copied - This could cause version conflicts"
                } Else {
                    Copy-Item $native $base_natives_path -Force -ErrorAction SilentlyContinue | Out-Null
                }
            }
        } Else {
            Write-Verbose "[Import-Package:Preparation] Any native files for $( $Options.Name ) $( $Options.Version ) will be copied from source at load time:"
            Write-Verbose "- Folder: $( $Options.Source )"
            Write-Verbose "- Note: There may not be any to load"
        }
    }

    $Options.NativePath = $base_natives_path
}