#!/bin/sh
# hectorsai installer.
#
#   curl -fsSL https://hectors.ai/install.sh | sh
#
# Downloads the latest release binary for your platform from the Homebrew tap
# repo's GitHub releases (the same artifacts the Homebrew cask and Nix package
# use) and installs it. Pure POSIX sh — no bash required.
#
# Environment overrides:
#   VERSION=v0.1.0      install a specific tag        (default: latest release)
#   BIN_DIR=$HOME/bin   install location              (default: /usr/local/bin,
#                                                       falling back to ~/.local/bin)
set -eu

REPO="incredico/homebrew-tap"
BINARY="hectorsai"

info() { printf '\033[1;32m==>\033[0m %s\n' "$*" >&2; }
err() {
  printf '\033[1;31merror:\033[0m %s\n' "$*" >&2
  exit 1
}

# download <url> <dest> — prefers curl, falls back to wget.
download() {
  if command -v curl >/dev/null 2>&1; then
    curl -fsSL "$1" -o "$2"
  elif command -v wget >/dev/null 2>&1; then
    wget -qO "$2" "$1"
  else
    err "need curl or wget to download files"
  fi
}

# latest_version — newest release tag, resolved from the web redirect rather
# than the api.github.com REST API. The REST API rate-limits unauthenticated
# callers to 60 requests/hour/IP (easy to exhaust behind shared NATs/CI); the
# plain https://github.com/OWNER/REPO/releases/latest URL instead 302-redirects
# to /releases/tag/<tag> and is not subject to that limit. Falls back to the
# REST API only if the redirect can't be read.
latest_version() {
  page="https://github.com/${REPO}/releases/latest"
  tag=""
  if command -v curl >/dev/null 2>&1; then
    # Follow redirects, discard the body, print the final URL, keep the tag.
    tag=$(curl -fsSL -o /dev/null -w '%{url_effective}' "$page" 2>/dev/null |
      sed -n 's#.*/releases/tag/##p')
  elif command -v wget >/dev/null 2>&1; then
    # wget logs each redirect's Location to stderr with -S; take the tag.
    tag=$(wget -S --spider "$page" 2>&1 |
      sed -n 's#.*/releases/tag/\([^ ]*\).*#\1#p' | tail -1 | tr -d '\r')
  fi

  # Fallback: the REST API (rate-limited, but better than failing outright).
  if [ -z "$tag" ]; then
    api="https://api.github.com/repos/${REPO}/releases/latest"
    if command -v curl >/dev/null 2>&1; then
      tag=$(curl -fsSL "$api" 2>/dev/null)
    elif command -v wget >/dev/null 2>&1; then
      tag=$(wget -qO- "$api" 2>/dev/null)
    fi
    tag=$(printf '%s' "$tag" | grep '"tag_name"' | head -1 |
      sed -E 's/.*"tag_name": *"([^"]+)".*/\1/')
  fi

  printf '%s' "$tag"
}

# install_dir — where to drop the binary, preferring a writable system path.
install_dir() {
  if [ -n "${BIN_DIR:-}" ]; then
    printf '%s' "$BIN_DIR"
  elif [ -w /usr/local/bin ]; then
    printf '/usr/local/bin'
  else
    printf '%s' "${HOME}/.local/bin"
  fi
}

# verify <file> <archive_name> <version> <tmp> — best-effort checksum check.
verify() {
  if command -v sha256sum >/dev/null 2>&1; then
    sha="sha256sum"
  elif command -v shasum >/dev/null 2>&1; then
    sha="shasum -a 256"
  else
    info "skipping checksum verification (no sha256sum/shasum)"
    return 0
  fi
  if ! download "https://github.com/${REPO}/releases/download/$3/checksums.txt" "$4/checksums.txt" 2>/dev/null; then
    info "skipping checksum verification (checksums.txt unavailable)"
    return 0
  fi
  want=$(grep " $2\$" "$4/checksums.txt" | awk '{ print $1 }')
  [ -n "$want" ] || {
    info "skipping checksum verification ($2 not listed)"
    return 0
  }
  got=$($sha "$1" | awk '{ print $1 }')
  [ "$want" = "$got" ] || err "checksum mismatch for $2 (expected $want, got $got)"
  info "checksum verified"
}

main() {
  os=$(uname -s)
  case "$os" in
    Linux) os="linux" ;;
    Darwin) os="darwin" ;;
    *) err "unsupported OS: $os — try Homebrew or Nix instead" ;;
  esac

  arch=$(uname -m)
  case "$arch" in
    x86_64 | amd64) arch="amd64" ;;
    aarch64 | arm64) arch="arm64" ;;
    *) err "unsupported architecture: $arch" ;;
  esac

  version="${VERSION:-}"
  [ -n "$version" ] || version=$(latest_version)
  [ -n "$version" ] || err "could not determine the latest release; set VERSION=vX.Y.Z"
  # Normalize to a leading "v" (release tags are v-prefixed; the archive name
  # strips it separately below). Avoids a 404 when a user passes VERSION=0.1.0.
  case "$version" in v*) ;; *) version="v$version" ;; esac

  # Archive filenames use the version without the leading "v" (see .goreleaser.yaml).
  archive="${BINARY}_${version#v}_${os}_${arch}.tar.gz"
  url="https://github.com/${REPO}/releases/download/${version}/${archive}"

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

  info "Downloading ${BINARY} ${version} (${os}/${arch})…"
  download "$url" "$tmp/$archive" || err "download failed: $url"

  verify "$tmp/$archive" "$archive" "$version" "$tmp"

  tar -xzf "$tmp/$archive" -C "$tmp" || err "failed to extract ${archive}"
  [ -f "$tmp/$BINARY" ] || err "archive did not contain ${BINARY}"

  bindir=$(install_dir)
  mkdir -p "$bindir"
  cp "$tmp/$BINARY" "$bindir/$BINARY"
  chmod 0755 "$bindir/$BINARY"

  info "Installed ${BINARY} ${version} → ${bindir}/${BINARY}"
  case ":$PATH:" in
    *":$bindir:"*) ;;
    *) info "${bindir} is not on your PATH — add it:  export PATH=\"${bindir}:\$PATH\"" ;;
  esac
  info "Sign in with '${BINARY} login', then run '${BINARY}'."
}

main "$@"
