#!/bin/sh
set -eu

binary="juno"
release_server="${JUNO_RELEASE_SERVER_URL:-https://releases.juno.futex.ai}"

need() {
  if ! command -v "$1" >/dev/null 2>&1; then
    echo "error: $1 is required" >&2
    exit 1
  fi
}

need curl
need sed
need tar
need uname

os="$(uname -s)"
arch="$(uname -m)"

case "$os:$arch" in
  Linux:x86_64|Linux:amd64)
    target="x86_64-unknown-linux-gnu"
    ;;
  Linux:aarch64|Linux:arm64)
    target="aarch64-unknown-linux-gnu"
    ;;
  Darwin:x86_64|Darwin:amd64)
    target="x86_64-apple-darwin"
    ;;
  Darwin:aarch64|Darwin:arm64)
    target="aarch64-apple-darwin"
    ;;
  *)
    echo "error: unsupported platform $os/$arch" >&2
    exit 1
    ;;
esac

metadata_url="${release_server%/}/releases/latest/$binary/$target"
metadata="$(curl -fsSL "$metadata_url")"

field() {
  printf '%s' "$metadata" | sed -n "s/.*\"$1\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p"
}

version="$(field version)"
asset_name="$(field asset_name)"
download_url="$(field download_url)"
sha256="$(field sha256)"

if [ -z "$version" ] || [ -z "$asset_name" ] || [ -z "$download_url" ]; then
  echo "error: release metadata from $metadata_url was incomplete" >&2
  exit 1
fi

if [ -z "$sha256" ]; then
  echo "error: release metadata from $metadata_url did not include a checksum" >&2
  exit 1
fi

case "$download_url" in
  http://*|https://*)
    archive_url="$download_url"
    ;;
  /*)
    archive_url="${release_server%/}$download_url"
    ;;
  *)
    archive_url="${release_server%/}/$download_url"
    ;;
esac

tmp_dir="$(mktemp -d 2>/dev/null || mktemp -d -t juno-install)"
trap 'rm -rf "$tmp_dir"' EXIT HUP INT TERM

archive="$tmp_dir/$asset_name"
curl -fsSL "$archive_url" -o "$archive"

if command -v sha256sum >/dev/null 2>&1; then
  printf '%s  %s\n' "$sha256" "$archive" | sha256sum -c - >/dev/null
elif command -v shasum >/dev/null 2>&1; then
  printf '%s  %s\n' "$sha256" "$archive" | shasum -a 256 -c - >/dev/null
else
  echo "error: sha256sum or shasum is required" >&2
  exit 1
fi

tar -xzf "$archive" -C "$tmp_dir"
binary_path="$tmp_dir/$binary-$version-$target/$binary"

if [ ! -f "$binary_path" ]; then
  echo "error: archive did not contain $binary" >&2
  exit 1
fi

if [ -n "${JUNO_INSTALL_DIR:-}" ]; then
  install_dir="$JUNO_INSTALL_DIR"
elif [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then
  install_dir="/usr/local/bin"
else
  if [ -z "${HOME:-}" ]; then
    echo "error: HOME is required when JUNO_INSTALL_DIR is not set" >&2
    exit 1
  fi
  install_dir="$HOME/.local/bin"
fi

mkdir -p "$install_dir"

if [ ! -w "$install_dir" ]; then
  echo "error: $install_dir is not writable; set JUNO_INSTALL_DIR to a writable directory" >&2
  exit 1
fi

cp "$binary_path" "$install_dir/$binary"
chmod 755 "$install_dir/$binary"

echo "installed $binary $version to $install_dir/$binary"

case ":${PATH:-}:" in
  *":$install_dir:"*)
    ;;
  *)
    echo "warning: $install_dir is not on PATH" >&2
    ;;
esac
