#!/usr/bin/env ruby

require "rbconfig"
require "digest/sha2"
require "fileutils"

CARGO_BINSTALL_VERSION = "1.4.3"

CHECKSUMS = {
  "x86_64-apple-darwin" => "71506ac1b15ed20a5f0b326d27883bed9d05d085c3b76a7828c9383636225dfe",
  "x86_64-unknown-linux-musl" => "d9f9876d9cc053827edb760775b9bacd091df70117c4d7f74b24f8f8749aa2b2",
  "x86_64-pc-windows-msvc" => "96f8325693ed00ccb96c7ae0d1da83e9c1c644d33d87175d4d4594f71246f283",
  "aarch64-apple-darwin" => "1cbc0ab3c12c3699379fb7f4640d194f71d4db2534d27b5c6849781920279721"
}

def infer_vendor
  case RbConfig::CONFIG["host_os"]
  when /linux/i
    "unknown-linux-musl"
  when /darwin/i
    "apple-darwin"
  when /mswin|mingw|cygwin/i
    "pc-windows-msvc"
  else
    raise "Unsupported host OS: #{RbConfig::CONFIG["host_os"]}"
  end
end

def infer_cpu
  case RbConfig::CONFIG["host_cpu"]
  when /x86_64/i, /x64/i
    "x86_64"
  when /aarch64/i, /arm64/i
    "aarch64"
  else
    raise "Unsupported host CPU: #{RbConfig::CONFIG["host_cpu"]}"
  end
end

def infer_target_triple
  vendor = infer_vendor
  cpu = infer_cpu

  "#{cpu}-#{vendor}"
end

def tmpdir
  return ENV["RUNNER_TEMP"] if ENV["RUNNER_TEMP"]

  require "tmpdir"
  @tmpdir ||= Dir.tmpdir
end

def download_and_save(triple, attempts = 3)
  checksum = CHECKSUMS.fetch(triple)
  ext = triple.include?("linux") ? "tgz" : "zip"
  url = "https://github.com/cargo-bins/cargo-binstall/releases/download/v#{CARGO_BINSTALL_VERSION}/cargo-binstall-#{triple}.#{ext}"
  filename = triple.include?("windows") ? "cargo-binstall.exe" : "cargo-binstall"
  outfile = File.join(tmpdir, filename)

  return outfile if File.exist?(outfile)

  puts("Downloading #{url}")
  download_file = File.join(tmpdir, "cargo-binstall-download.#{ext}")

  # download and follow redirects
  system("curl", "-sSL", "-o", download_file, url) || raise("Download failed")

  response_body = File.binread(download_file)

  raise "Checksum mismatch" unless Digest::SHA256.hexdigest(response_body) == checksum
  puts("Verified checksum")

  # Unzip on macOS
  if ext == "zip"
    system("unzip -p #{download_file} #{filename} > #{outfile}")
  elsif ext == "tgz"
    system("tar xzf #{download_file} -O > #{outfile}")
  end

  FileUtils.rm(download_file)

  ret = outfile
  File.chmod(0o755, ret)
  ret
rescue => e
  if attempts > 0
    warn("Error when downloading: #{e.message}, retrying in 3 seconds...")
    sleep(3)
    download_and_save(triple, attempts - 1)
  else
    raise
  end
end

def install_cargo_binstall
  puts("::group::Installing cargo-binstall")
  target_triple = infer_target_triple
  ret = download_and_save(target_triple)
  puts("::endgroup::")
  ret
end

def main
  exe = install_cargo_binstall
  exec(exe, *ARGV)
end

main
