#!/bin/sh
# CloudQuery CLI installer.
#
#   curl -fsSL https://cloudquery.io/install.sh | sh
#
# Env vars:
#   CQ_VERSION      Pin an exact CLI version (e.g. "6.42.2"). Defaults to the latest CLI release.
#   CQ_INSTALL_DIR  Where to install the binary. Defaults to "$HOME/.cloudquery/bin" (no sudo needed).
set -eu

repo="cloudquery/cloudquery"
install_dir="${CQ_INSTALL_DIR:-$HOME/.cloudquery/bin}"
version="${CQ_VERSION:-}"

fail() {
  echo "cloudquery install: $1" >&2
  exit 1
}

command -v curl >/dev/null 2>&1 || fail "curl is required. See https://cloudquery.io/download for other install options."

os=$(uname -s)
case "$os" in
  Darwin) os="darwin" ;;
  Linux) os="linux" ;;
  *) fail "unsupported OS '$os'. See https://cloudquery.io/download for other install options." ;;
esac

arch=$(uname -m)
case "$arch" in
  x86_64 | amd64) arch="amd64" ;;
  arm64 | aarch64) arch="arm64" ;;
  *) fail "unsupported architecture '$arch'. See https://cloudquery.io/download for other install options." ;;
esac

if [ -z "$version" ]; then
  # This repo also cuts plugin/SDK releases, and they vastly outnumber CLI ones, so GitHub's
  # generic "latest release" is wrong here and a single page of results can contain no cli-v
  # tag at all. Scan several pages, then pick the highest version rather than the most recently
  # created — a backported patch is cut after a newer minor.
  cli_versions=""
  page=1
  while [ "$page" -le 3 ]; do
    releases=$(curl -fsSL "https://api.github.com/repos/$repo/releases?per_page=100&page=$page") \
      || fail "could not reach the GitHub releases API (it may be rate-limited). Set CQ_VERSION to pin a release explicitly."

    # The anchored pattern also drops pre-release tags such as cli-v6.43.0-rc1.
    page_versions=$(printf '%s' "$releases" \
      | grep '"tag_name"' \
      | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/' \
      | grep -E '^cli-v[0-9]+\.[0-9]+\.[0-9]+$' \
      | sed 's/^cli-v//') || page_versions=""

    if [ -n "$page_versions" ]; then
      cli_versions="$cli_versions$page_versions
"
    fi

    page=$((page + 1))
  done

  latest=$(printf '%s' "$cli_versions" | grep -v '^$' | sort -t. -k1,1n -k2,2n -k3,3n | tail -n1)
  [ -n "$latest" ] || fail "could not resolve the latest CLI version (GitHub API may be rate-limited). Set CQ_VERSION to pin a release explicitly."
  tag="cli-v$latest"
else
  tag="cli-v$version"
fi

asset="cloudquery_${os}_${arch}"
base_url="https://github.com/$repo/releases/download/$tag"

tmp_dir=$(mktemp -d)
trap 'rm -rf "$tmp_dir"' EXIT INT TERM

echo "Downloading CloudQuery CLI ($tag, $os/$arch)..."
curl -fsSL "$base_url/$asset" -o "$tmp_dir/cloudquery" || fail "download failed for $asset at $tag. Check that the version exists: https://github.com/$repo/releases"
curl -fsSL "$base_url/checksums.txt" -o "$tmp_dir/checksums.txt" || fail "could not download checksums.txt for $tag."

expected_checksum=$(grep " $asset\$" "$tmp_dir/checksums.txt" | awk '{ print $1 }')
[ -n "$expected_checksum" ] || fail "no checksum entry found for $asset in checksums.txt, aborting."

if command -v sha256sum >/dev/null 2>&1; then
  actual_checksum=$(sha256sum "$tmp_dir/cloudquery" | awk '{ print $1 }')
elif command -v shasum >/dev/null 2>&1; then
  actual_checksum=$(shasum -a 256 "$tmp_dir/cloudquery" | awk '{ print $1 }')
else
  fail "neither sha256sum nor shasum is available to verify the download, aborting."
fi

[ "$expected_checksum" = "$actual_checksum" ] || fail "checksum mismatch for $asset (expected $expected_checksum, got $actual_checksum), aborting."

mkdir -p "$install_dir"
chmod +x "$tmp_dir/cloudquery"
mv "$tmp_dir/cloudquery" "$install_dir/cloudquery"

echo "Installed cloudquery ($tag) to $install_dir/cloudquery"

case ":$PATH:" in
  *":$install_dir:"*) ;;
  *)
    echo "Note: $install_dir is not on your PATH. Add it, e.g.:"
    echo "  export PATH=\"$install_dir:\$PATH\""
    ;;
esac
