#!/bin/sh

set -eu

BINARY_NAME="requesthunt"
DEFAULT_INSTALL_DIR="/usr/local/bin"
FALLBACK_INSTALL_DIR="${HOME:-}/.local/bin"
VERSION="${REQUESTHUNT_INSTALL_VERSION:-latest}"
BASE_URL="${REQUESTHUNT_INSTALL_BASE_URL:-https://github.com/ReScienceLab/requesthunt-cli/releases}"
TMP_DIR=""

log() { printf '%s\n' "$*" >&2; }
fail() { log "error: $*"; exit 1; }

cleanup() {
  [ -n "$TMP_DIR" ] && [ -d "$TMP_DIR" ] && rm -rf "$TMP_DIR"
}

detect_target() {
  OS=$(uname -s 2>/dev/null)
  ARCH=$(uname -m 2>/dev/null)

  case "$OS" in
    Darwin) OS_PART="apple-darwin" ;;
    Linux)  OS_PART="unknown-linux-gnu" ;;
    *)      fail "unsupported OS: ${OS:-unknown}" ;;
  esac

  case "$ARCH" in
    x86_64 | amd64)  ARCH_PART="x86_64" ;;
    arm64 | aarch64)  ARCH_PART="aarch64" ;;
    *)                fail "unsupported arch: ${ARCH:-unknown}" ;;
  esac

  printf '%s\n' "${ARCH_PART}-${OS_PART}"
}

release_url() {
  if [ "$VERSION" = "latest" ]; then
    printf '%s\n' "${BASE_URL}/latest/download/$1"
  else
    printf '%s\n' "${BASE_URL}/download/${VERSION}/$1"
  fi
}

download() {
  curl --fail --location --silent --show-error \
    --connect-timeout 10 \
    --max-time "${REQUESTHUNT_INSTALL_MAX_TIME:-300}" \
    --output "$2" "$1"
}

verify_checksum() {
  if command -v sha256sum >/dev/null 2>&1; then
    ACTUAL=$(sha256sum "$1" | awk '{print $1}')
  elif command -v shasum >/dev/null 2>&1; then
    ACTUAL=$(shasum -a 256 "$1" | awk '{print $1}')
  else
    log "warning: no sha256 tool found, skipping checksum"
    return 0
  fi

  EXPECTED=$(awk 'NR==1{print $1}' "$2")
  [ "$EXPECTED" = "$ACTUAL" ] || fail "checksum mismatch"
  log "checksum verified"
}

choose_install_dir() {
  if [ -n "${REQUESTHUNT_INSTALL_BIN_DIR:-}" ]; then
    mkdir -p "$REQUESTHUNT_INSTALL_BIN_DIR"
    printf '%s\n' "$REQUESTHUNT_INSTALL_BIN_DIR"
    return
  fi
  if mkdir -p "$DEFAULT_INSTALL_DIR" >/dev/null 2>&1 && [ -w "$DEFAULT_INSTALL_DIR" ]; then
    printf '%s\n' "$DEFAULT_INSTALL_DIR"
    return
  fi
  [ -n "${HOME:-}" ] || fail "HOME must be set"
  mkdir -p "$FALLBACK_INSTALL_DIR"
  printf '%s\n' "$FALLBACK_INSTALL_DIR"
}

main() {
  command -v curl >/dev/null 2>&1 || fail "curl is required"

  TARGET=$(detect_target)
  ARCHIVE="${BINARY_NAME}-${TARGET}.tar.gz"

  TMP_DIR=$(mktemp -d 2>/dev/null || mktemp -d -t requesthunt-install)
  trap cleanup EXIT INT HUP TERM

  log "downloading ${ARCHIVE}"
  download "$(release_url "$ARCHIVE")" "${TMP_DIR}/${ARCHIVE}"

  if download "$(release_url "${ARCHIVE}.sha256")" "${TMP_DIR}/${ARCHIVE}.sha256" 2>/dev/null; then
    verify_checksum "${TMP_DIR}/${ARCHIVE}" "${TMP_DIR}/${ARCHIVE}.sha256"
  fi

  tar -xzf "${TMP_DIR}/${ARCHIVE}" -C "${TMP_DIR}"

  INSTALL_DIR=$(choose_install_dir)
  cp "${TMP_DIR}/${BINARY_NAME}" "${INSTALL_DIR}/${BINARY_NAME}"
  chmod 755 "${INSTALL_DIR}/${BINARY_NAME}"

  printf '\nrequesthunt installed to %s/%s\n' "$INSTALL_DIR" "$BINARY_NAME"
  printf 'next: requesthunt auth login\n'

  case ":${PATH:-}:" in
    *":${INSTALL_DIR}:"*) ;;
    *) printf 'note: add %s to your PATH\n' "$INSTALL_DIR" ;;
  esac
}

main "$@"
