#!/bin/sh
# Octopoda CLI installer: curl -fsSL https://get.octopoda.dev | sh
#
# Downloads the latest octopoda binary for this machine, checks its SHA-256
# against the signed release list, verifies its minisign signature when
# minisign is installed, and puts it on your PATH.
#
# Options (environment): OCTOPODA_INSTALL_DIR to choose where it goes,
# OCTOPODA_VERSION to pin a version.
set -eu

BASE="${OCTOPODA_RELEASES_URL:-https://get.octopoda.dev}"
PUBKEY="RWRvnVbBCAfW9Lir0RvVCkbDqCYyXuYJ0o6BIQhqedeMIMAiXLrCfvR8"

say() { printf '%s\n' "$*"; }
fail() { printf 'octopoda install: %s\n' "$*" >&2; exit 1; }
need() { command -v "$1" >/dev/null 2>&1 || fail "needs $1"; }

need uname
if command -v curl >/dev/null 2>&1; then
  get() { curl -fsSL "$1" -o "$2"; }
elif command -v wget >/dev/null 2>&1; then
  get() { wget -qO "$2" "$1"; }
else
  fail "needs curl or wget"
fi

os="$(uname -s)"
case "$os" in
  Darwin) os=darwin ;;
  Linux) os=linux ;;
  *) fail "unsupported system $os (macOS and Linux are supported; on Windows use WSL)" ;;
esac
arch="$(uname -m)"
case "$arch" in
  x86_64 | amd64) arch=amd64 ;;
  arm64 | aarch64) arch=arm64 ;;
  *) fail "unsupported CPU $arch" ;;
esac

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

if [ -n "${OCTOPODA_VERSION:-}" ]; then
  manifest="$BASE/v${OCTOPODA_VERSION#v}/manifest.json"
else
  manifest="$BASE/latest.json"
fi
get "$manifest" "$tmp/manifest.json" || fail "could not download the release list from $BASE"

# Read version, path and checksum for this platform without needing jq.
platform="$os-$arch"
version="$(sed -n 's/.*"version"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$tmp/manifest.json" | head -n1)"
entry="$(tr -d '\n ' <"$tmp/manifest.json" | sed -n "s/.*\"$platform\":{\([^}]*\)}.*/\1/p")"
path="$(printf '%s' "$entry" | sed -n 's/.*"path":"\([^"]*\)".*/\1/p')"
sha="$(printf '%s' "$entry" | sed -n 's/.*"sha256":"\([^"]*\)".*/\1/p')"
[ -n "$version" ] && [ -n "$path" ] && [ -n "$sha" ] || fail "no release for $platform"

say "Downloading octopoda $version for $platform..."
get "$BASE/$path" "$tmp/octopoda" || fail "download failed"

if command -v sha256sum >/dev/null 2>&1; then
  got="$(sha256sum "$tmp/octopoda" | cut -d' ' -f1)"
else
  got="$(shasum -a 256 "$tmp/octopoda" | cut -d' ' -f1)"
fi
[ "$got" = "$sha" ] || fail "checksum mismatch; not installing"

if command -v minisign >/dev/null 2>&1; then
  get "$BASE/$path.minisig" "$tmp/octopoda.minisig" || fail "could not download the signature"
  minisign -Vm "$tmp/octopoda" -x "$tmp/octopoda.minisig" -P "$PUBKEY" >/dev/null 2>&1 || fail "signature check failed; not installing"
  say "Signature verified."
fi
chmod 0755 "$tmp/octopoda"

dir="${OCTOPODA_INSTALL_DIR:-}"
if [ -z "$dir" ]; then
  if [ -w /usr/local/bin ]; then dir=/usr/local/bin; else dir="$HOME/.local/bin"; fi
fi
mkdir -p "$dir"
mv "$tmp/octopoda" "$dir/octopoda"

say ""
say "Installed octopoda $version to $dir/octopoda"
case ":$PATH:" in
  *":$dir:"*) ;;
  *) say "Add it to your PATH: export PATH=\"$dir:\$PATH\"" ;;
esac
say ""
say "Next:"
say "  octopoda login     Sign in (opens your browser)"
say "  octopoda scan      Scan the project in this folder"
