Param(
  [string]$Repo = "yuval-a/snippets",
  [string]$BinName = "snippets",
  [string]$InstallDir = "$env:LocalAppData\Programs\snippets"
)

$ErrorActionPreference = "Stop"

function Get-LatestAssetUrl {
  param([string]$Repo, [string]$Suffix)
  $api = "https://api.github.com/repos/$Repo/releases/latest"
  $json = Invoke-WebRequest -UseBasicParsing -Uri $api | Select-Object -ExpandProperty Content | ConvertFrom-Json
  $asset = $json.assets | Where-Object { $_.browser_download_url -like "*${Suffix}" } | Select-Object -First 1
  if (-not $asset) { throw "No asset with suffix '$Suffix'" }
  return $asset.browser_download_url
}

Write-Host "Detecting latest release…"
$suffix = "windows.zip"
try {
  $assetUrl = Get-LatestAssetUrl -Repo $Repo -Suffix $suffix
} catch {
  $assetUrl = $null
}

if (-not $assetUrl) {
  Write-Warning "No prebuilt asset found. Attempting cargo fallback…"
  $cargo = Get-Command cargo -ErrorAction SilentlyContinue
  if ($cargo) {
    Write-Host "Running: cargo install --git https://github.com/$Repo.git $BinName"
    & cargo install --git "https://github.com/$Repo.git" $BinName
    Write-Host "Installed via cargo. Ensure %USERPROFILE%\.cargo\bin is on PATH."
    return
  } else {
    throw "Rust (cargo) not found and no asset available. Install Rust from https://rustup.rs and retry."
  }
}

$sumUrl = "$assetUrl.sha256"

$tmp = New-Item -ItemType Directory -Path ([System.IO.Path]::Combine($env:TEMP, "snippets-install-" + [System.Guid]::NewGuid().ToString()))
$archive = Join-Path $tmp.FullName "snippets.zip"
$sumfile = Join-Path $tmp.FullName "snippets.zip.sha256"

Write-Host "Downloading $assetUrl"
Invoke-WebRequest -UseBasicParsing -Uri $assetUrl -OutFile $archive

try {
  Write-Host "Downloading checksum"
  Invoke-WebRequest -UseBasicParsing -Uri $sumUrl -OutFile $sumfile
  Write-Host "Verifying checksum"
  $expected = (Get-Content $sumfile).Split(' ')[0]
  $actual = (Get-FileHash -Algorithm SHA256 $archive).Hash.ToLower()
  if ($expected.ToLower() -ne $actual) { throw "checksum mismatch" }
} catch {
  Write-Warning "Skipping checksum verification: $_"
}

Write-Host "Extracting archive"
Expand-Archive -LiteralPath $archive -DestinationPath $tmp.FullName -Force

$binPath = Join-Path $tmp.FullName "$BinName.exe"
if (-not (Test-Path $binPath)) {
  $binPath = Get-ChildItem -Path $tmp.FullName -Recurse -Filter "$BinName.exe" | Select-Object -First 1 | ForEach-Object { $_.FullName }
}
if (-not $binPath) { throw "Binary '$BinName.exe' not found in archive" }

New-Item -ItemType Directory -Force -Path $InstallDir | Out-Null
Copy-Item -Force -LiteralPath $binPath -Destination (Join-Path $InstallDir "$BinName.exe")
Write-Host "Installed: $InstallDir\$BinName.exe"

# Add to PATH for current user if missing
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
if (-not $userPath) { $userPath = '' }
if (-not ($userPath.Split(';') -contains $InstallDir)) {
  [Environment]::SetEnvironmentVariable('Path', ($userPath + ';' + $InstallDir), 'User')
  Write-Host "Added to PATH (User). You may need to open a new shell."
}

Write-Host "Done."
