functions/_Install-Vendir.ps1

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

<#
.SYNOPSIS
    Downloads the vendir binary for the current platform.

.DESCRIPTION
    Downloads the correct platform-specific vendir binary from GitHub releases
    and installs it into the module's local bin/ directory. Handles OS detection
    (Windows, macOS, Linux), architecture mapping (x64, arm64), and sets
    executable permissions on non-Windows platforms.

.PARAMETER Version
    The version of vendir to download. Defaults to the module-level
    $script:VendirVersion variable.

.EXAMPLE
    _Install-Vendir

    Downloads the default version of vendir for the current platform into the
    module's bin/ directory.

.EXAMPLE
    _Install-Vendir -Version '0.45.1'

    Downloads vendir v0.45.1 for the current platform.
#>

function _Install-Vendir {
    [CmdletBinding()]
    param (
        [Parameter()]
        [string] $Version = $script:VendirVersion
    )

    # Determine OS
    if ($IsWindows) {
        $os = 'windows'
        $ext = '.exe'
    }
    elseif ($IsMacOS) {
        $os = 'darwin'
        $ext = ''
    }
    elseif ($IsLinux) {
        $os = 'linux'
        $ext = ''
    }
    else {
        throw "Unsupported operating system. Unable to determine platform for vendir download."
    }

    # Determine architecture
    $arch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture
    switch ($arch) {
        'X64'   { $archStr = 'amd64' }
        'Arm64' { $archStr = 'arm64' }
        default { throw "Unsupported architecture: $arch" }
    }

    $binaryName = "vendir$ext"
    $downloadUrl = "https://github.com/carvel-dev/vendir/releases/download/v${Version}/vendir-${os}-${archStr}${ext}"

    $binDir = Join-Path $PSScriptRoot '..' 'bin'
    $binDir = [System.IO.Path]::GetFullPath($binDir)
    $destPath = Join-Path $binDir $binaryName

    if (-not (Test-Path $binDir)) {
        New-Item -ItemType Directory -Path $binDir -Force | Out-Null
    }

    Write-Information "Downloading vendir v${Version} (${os}/${archStr})..."
    try {
        Invoke-WebRequest -Uri $downloadUrl -OutFile $destPath -ErrorAction Stop
    }
    catch {
        throw "Failed to download vendir from ${downloadUrl}: $_"
    }

    # Verify SHA256 checksum
    $downloadFilename = "vendir-${os}-${archStr}${ext}"
    $checksumsUrl = "https://github.com/carvel-dev/vendir/releases/download/v${Version}/checksums.txt"
    try {
        $checksumsContent = (Invoke-WebRequest -Uri $checksumsUrl -ErrorAction Stop).Content
        $checksumLine = ($checksumsContent -split "`n") | Where-Object { $_ -match $downloadFilename }
        if ($checksumLine) {
            $expectedHash = ($checksumLine -split '\s+')[0].Trim()
            $actualHash = (Get-FileHash -Path $destPath -Algorithm SHA256).Hash
            if ($actualHash -ne $expectedHash) {
                throw "Checksum mismatch for ${downloadFilename}: expected ${expectedHash}, got ${actualHash}"
            }
            Write-Information "Checksum verified for vendir v${Version}."
        }
        else {
            Write-Warning "Could not find checksum entry for ${downloadFilename} in checksums.txt"
        }
    }
    catch [System.Exception] {
        if ($_.Exception.Message -match 'Checksum mismatch') {
            throw
        }
        Write-Warning "Could not verify checksum for vendir v${Version}: $_"
    }

    # Set executable permissions on non-Windows platforms
    if (-not $IsWindows) {
        chmod +x $destPath
    }

    Write-Information "vendir v${Version} installed to: $destPath"

    return $destPath
}