# Generated by bincast - https://github.com/benelser/bincast
# Install delite-core on Windows
#Requires -Version 5.1
$ErrorActionPreference = "Stop"

$Repo = "benelser/durable"
$Binary = "delite"
$Name = "delite-core"
$InstallDir = "$env:USERPROFILE\.local\bin"

function Check-RepoAccess {
    try {
        $response = Invoke-WebRequest -Uri "https://api.github.com/repos/$Repo" -UseBasicParsing -ErrorAction SilentlyContinue
    } catch {
        $statusCode = $_.Exception.Response.StatusCode.value__
        if ($statusCode -eq 404) {
            $script:IsPrivate = $true
            try { $null = & gh --version 2>$null } catch {
                Write-Host ""
                Write-Host "Error: $Repo appears to be a private repository."
                Write-Host ""
                Write-Host "  Private repos require the GitHub CLI (gh) for authenticated downloads."
                Write-Host ""
                Write-Host "  Install gh:"
                Write-Host "    winget install GitHub.cli"
                Write-Host ""
                Write-Host "  Then authenticate:"
                Write-Host "    gh auth login"
                Write-Host ""
                exit 1
            }
        }
    }
}

function Main {
    Check-RepoAccess
    $Platform = Detect-Platform
    $Version = Fetch-LatestVersion
    Download-And-Install -Platform $Platform -Version $Version
    Ensure-Path
    Write-Host ""
    Write-Host "$Binary $Version installed to $InstallDir\$Binary.exe"
}

function Detect-Platform {
    $Arch = $env:PROCESSOR_ARCHITECTURE
    switch ($Arch) {
        "AMD64" { return "x86_64-pc-windows-msvc" }
        "ARM64" { return "aarch64-pc-windows-msvc" }
        default {
            Write-Error "Unsupported architecture: $Arch"
            exit 1
        }
    }
}

function Fetch-LatestVersion {
    # Try gh CLI first (works for private repos)
    try {
        $version = & gh release view --repo $Repo --json tagName --jq .tagName 2>$null
        if ($version) { return $version }
    } catch {}
    # Fallback to API
    $Release = Invoke-RestMethod -Uri "https://api.github.com/repos/$Repo/releases/latest"
    return $Release.tag_name
}

function Download-And-Install {
    param($Platform, $Version)

    $Archive = "$Name-$Platform.zip"

    # Try gh CLI first (supports private repos)
    $downloaded = $false
    try {
        & gh release download $Version --repo $Repo --pattern $Archive --pattern "$Archive.sha256" --dir $env:TEMP 2>$null
        if (Test-Path "$env:TEMP\$Archive") { $downloaded = $true }
    } catch {}

    $TmpDir = New-TemporaryFile | ForEach-Object {
        Remove-Item $_
        New-Item -ItemType Directory -Path "$_.dir"
    }

    try {
        if (-not $downloaded) {
            $Url = "https://github.com/$Repo/releases/download/$Version/$Archive"
            Write-Host "Downloading $Url"
            Invoke-WebRequest -Uri $Url -OutFile "$TmpDir\$Archive"
            Invoke-WebRequest -Uri "$Url.sha256" -OutFile "$TmpDir\$Archive.sha256" -ErrorAction SilentlyContinue
        } else {
            Move-Item "$env:TEMP\$Archive" "$TmpDir\$Archive"
            if (Test-Path "$env:TEMP\$Archive.sha256") {
                Move-Item "$env:TEMP\$Archive.sha256" "$TmpDir\$Archive.sha256"
            }
        }

        # Verify checksum if available
        if (Test-Path "$TmpDir\$Archive.sha256") {
            $Expected = (Get-Content "$TmpDir\$Archive.sha256").Split(" ")[0]
            $Actual = (Get-FileHash "$TmpDir\$Archive" -Algorithm SHA256).Hash.ToLower()
            if ($Expected -ne $Actual) {
                Write-Error "Checksum mismatch: expected $Expected, got $Actual"
                exit 1
            }
        }

        Expand-Archive -Path "$TmpDir\$Archive" -DestinationPath $TmpDir -Force

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

        Copy-Item "$TmpDir\$Binary.exe" "$InstallDir\$Binary.exe" -Force
    }
    finally {
        Remove-Item -Recurse -Force $TmpDir -ErrorAction SilentlyContinue
    }
}

function Ensure-Path {
    $UserPath = [Environment]::GetEnvironmentVariable("PATH", "User")
    if ($UserPath -notlike "*$InstallDir*") {
        [Environment]::SetEnvironmentVariable("PATH", "$InstallDir;$UserPath", "User")
        Write-Host "Added $InstallDir to your PATH (restart your shell to pick it up)"
    }
}

Main
