#!/usr/bin/env sh
# SensAI CLI installer — downloads the correct binary for your OS/arch,
# verifies the SHA-256 checksum, and installs to /usr/local/bin or
# $HOME/.local/bin as a fallback.
set -eu

REPO="${SENSAI_RELEASE_REPO:-immunisense/sensai-cli}"
BINARY="sensai-cli"
PROXY_BASE_URL="${SENSAI_BASE_URL:-https://sensai.immunisense.com}"
RELEASE_BASE_URL="${SENSAI_RELEASE_BASE_URL:-${PROXY_BASE_URL}/releases/download}"
DOWNLOAD_RETRIES="${SENSAI_DOWNLOAD_RETRIES:-30}"
DOWNLOAD_RETRY_DELAY="${SENSAI_DOWNLOAD_RETRY_DELAY:-2}"

# ── Colors ──────────────────────────────────────────────────────────
# Generate a real ESC byte once, then build sequences from it.
# This is portable across POSIX sh, dash, bash, and zsh.
ESC=$(printf '\033')

if [ -t 1 ] || [ "${FORCE_COLOR:-}" = "1" ]; then
  GOLD="${ESC}[38;2;196;160;53m"
  GRAY="${ESC}[38;2;155;155;155m"
  WHITE="${ESC}[1;37m"
  GREEN="${ESC}[38;2;126;200;126m"
  RED="${ESC}[38;2;224;82;82m"
  DIM="${ESC}[2m"
  BOLD="${ESC}[1m"
  RESET="${ESC}[0m"
else
  GOLD='' GRAY='' WHITE='' GREEN='' RED='' DIM='' BOLD='' RESET=''
fi

info()  { printf '  %s▸%s %s\n' "$GOLD" "$RESET" "$1"; }
ok()    { printf '  %s✓%s %s\n' "$GREEN" "$RESET" "$1"; }
err()   { printf '  %s✗%s %s\n' "$RED" "$RESET" "$1" >&2; }
dim()   { printf '  %s%s%s\n' "$DIM" "$1" "$RESET"; }

fetch_latest_version() {
  VERSION_FROM_PROXY=$(curl -fsSL "${PROXY_BASE_URL}/v1/version" 2> /dev/null \
    | sed -n 's/.*"version": *"\([^"]*\)".*/\1/p' || true)
  if [ -n "${VERSION_FROM_PROXY}" ]; then
    printf '%s\n' "${VERSION_FROM_PROXY}"
    return 0
  fi

  if [ -n "${GITHUB_TOKEN:-}" ]; then
    VERSION_FROM_GITHUB=$(curl -fsSL \
      -H "Authorization: Bearer ${GITHUB_TOKEN}" \
      -H "Accept: application/vnd.github+json" \
      "https://api.github.com/repos/${REPO}/releases/latest" 2> /dev/null \
      | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' || true)
  else
    VERSION_FROM_GITHUB=$(curl -fsSL "https://api.github.com/repos/${REPO}/releases/latest" 2> /dev/null \
      | sed -n 's/.*"tag_name": *"\([^"]*\)".*/\1/p' || true)
  fi

  if [ -n "${VERSION_FROM_GITHUB}" ]; then
    printf '%s\n' "${VERSION_FROM_GITHUB}"
    return 0
  fi

  return 1
}

download_with_retries() {
  URL="$1"
  DEST="$2"
  ATTEMPT=1

  while [ "$ATTEMPT" -le "$DOWNLOAD_RETRIES" ]; do
      if [ -n "${GITHUB_TOKEN:-}" ]; then
        if curl -fsSL -H "Authorization: Bearer ${GITHUB_TOKEN}" "$URL" -o "$DEST"; then
          return 0
        fi
      else
        if curl -fsSL "$URL" -o "$DEST"; then
          return 0
        fi
    fi

    if [ "$ATTEMPT" -eq "$DOWNLOAD_RETRIES" ]; then
      err "Failed to download after ${DOWNLOAD_RETRIES} attempts"
      return 1
    fi

    sleep "$DOWNLOAD_RETRY_DELAY"
    ATTEMPT=$((ATTEMPT + 1))
  done
}

checksum_for_archive() {
  CHECKSUM_ARCHIVE="$1"
  CHECKSUM_FILE="$2"

  awk -v archive="$CHECKSUM_ARCHIVE" '
    {
      file = $2
      sub(/^\*/, "", file)
      if (file == archive || file == "./" archive) {
        print $1
        found = 1
        exit
      }
    }
    END {
      if (!found) {
        exit 1
      }
    }
  ' "$CHECKSUM_FILE"
}

archive_sha256() {
  HASH_ARCHIVE="$1"

  if command -v sha256sum > /dev/null 2>&1; then
    HASH_VALUE=$(sha256sum "$HASH_ARCHIVE" 2>/dev/null | awk '{print $1}' || true)
    if [ -n "$HASH_VALUE" ]; then
      printf '%s\n' "$HASH_VALUE"
      return 0
    fi
  fi

  if command -v shasum > /dev/null 2>&1; then
    HASH_VALUE=$(shasum -a 256 "$HASH_ARCHIVE" 2>/dev/null | awk '{print $1}' || true)
    if [ -n "$HASH_VALUE" ]; then
      printf '%s\n' "$HASH_VALUE"
      return 0
    fi
  fi

  return 1
}

path_has_dir() {
  case ":${PATH:-}:" in
    *":$1:"*) return 0 ;;
    *) return 1 ;;
  esac
}

can_prompt_sudo() {
  command -v sudo > /dev/null 2>&1 && [ -e /dev/tty ]
}

# ── Header ──────────────────────────────────────────────────────────
printf '\n'
printf '  %s%sSensAI%s %s— installer%s\n' "$GOLD" "$BOLD" "$RESET" "$GRAY" "$RESET"
printf '\n'

# ── Resolve version ─────────────────────────────────────────────────
VERSION="${SENSAI_VERSION:-}"
if [ -z "$VERSION" ]; then
  VERSION=$(fetch_latest_version || true)
fi

if [ -z "$VERSION" ]; then
  err "Could not determine latest version"
  dim "Tried ${PROXY_BASE_URL}/v1/version and GitHub releases"
  if [ -z "${GITHUB_TOKEN:-}" ]; then
    dim "Set GITHUB_TOKEN for private repo access:"
    printf '  %sGITHUB_TOKEN=ghp_xxx curl -fsSL %s/install | bash%s\n' "$WHITE" "$PROXY_BASE_URL" "$RESET"
  fi
  exit 1
fi

# ── Detect platform ─────────────────────────────────────────────────
OS=$(uname -s | tr '[:upper:]' '[:lower:]')
case "$OS" in
  linux)  OS="Linux" ;;
  darwin) OS="Darwin" ;;
  *)
    err "Unsupported OS: $OS"
    exit 1
    ;;
esac

ARCH=$(uname -m)
case "$ARCH" in
  x86_64 | amd64)  ARCH="x86_64" ;;
  aarch64 | arm64) ARCH="arm64" ;;
  *)
    err "Unsupported architecture: $ARCH"
    exit 1
    ;;
esac

info "Downloading ${WHITE}sensai-cli ${VERSION}${RESET} ${GRAY}(${OS}/${ARCH})${RESET}"

# ── Download ────────────────────────────────────────────────────────
VER="${VERSION#v}"
ARCHIVE="${BINARY}_${VER}_${OS}_${ARCH}.tar.gz"
BASE_URL="${RELEASE_BASE_URL}/${VERSION}"

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

download_with_retries "${BASE_URL}/${ARCHIVE}" "${TMP}/${ARCHIVE}"
download_with_retries "${BASE_URL}/checksums.txt" "${TMP}/checksums.txt"

# ── Verify checksum ─────────────────────────────────────────────────
info "Verifying checksum"
cd "$TMP"
EXPECTED_SUM=$(checksum_for_archive "$ARCHIVE" checksums.txt || true)
if [ -z "$EXPECTED_SUM" ]; then
  err "Checksum entry not found for ${ARCHIVE}"
  exit 1
fi

ACTUAL_SUM=$(archive_sha256 "$ARCHIVE" || true)
if [ -z "$ACTUAL_SUM" ]; then
  err "No sha256sum or shasum found — cannot verify download integrity"
  err "Install sha256sum (coreutils) or shasum (perl) and retry."
  exit 1
fi

EXPECTED_SUM=$(printf '%s' "$EXPECTED_SUM" | tr '[:upper:]' '[:lower:]')
ACTUAL_SUM=$(printf '%s' "$ACTUAL_SUM" | tr '[:upper:]' '[:lower:]')
if [ "$EXPECTED_SUM" != "$ACTUAL_SUM" ]; then
  err "Checksum verification failed"
  dim "Expected: ${EXPECTED_SUM}"
  dim "Actual:   ${ACTUAL_SUM}"
  exit 1
fi
cd - > /dev/null

# ── Extract ─────────────────────────────────────────────────────────
info "Extracting"
tar -xzf "${TMP}/${ARCHIVE}" -C "$TMP"
BIN_SRC=$(find "$TMP" -name "$BINARY" -type f | head -1)
if [ -z "$BIN_SRC" ]; then
  err "Binary not found in archive"
  exit 1
fi

# ── Install ─────────────────────────────────────────────────────────
USE_SUDO=0
if [ -n "${SENSAI_INSTALL_DIR:-}" ]; then
  INSTALL_DIR="$SENSAI_INSTALL_DIR"
elif [ -d /usr/local/bin ] && [ -w /usr/local/bin ]; then
  INSTALL_DIR="/usr/local/bin"
elif path_has_dir "/usr/local/bin" && can_prompt_sudo; then
  INSTALL_DIR="/usr/local/bin"
  USE_SUDO=1
elif [ -d /opt/homebrew/bin ] && [ -w /opt/homebrew/bin ] && path_has_dir "/opt/homebrew/bin"; then
  INSTALL_DIR="/opt/homebrew/bin"
elif [ "$(id -u)" -eq 0 ]; then
  INSTALL_DIR="/usr/local/bin"
  mkdir -p "$INSTALL_DIR"
else
  INSTALL_DIR="${HOME}/.local/bin"
  mkdir -p "$INSTALL_DIR"
fi

if [ "$USE_SUDO" -eq 1 ]; then
  info "Installing to ${WHITE}${INSTALL_DIR}${RESET} with sudo"
  if ! sudo mkdir -p "$INSTALL_DIR" || ! sudo install -m 0755 "$BIN_SRC" "${INSTALL_DIR}/${BINARY}"; then
    err "Could not install to ${INSTALL_DIR} with sudo"
    dim "Falling back to ${HOME}/.local/bin"
    INSTALL_DIR="${HOME}/.local/bin"
    mkdir -p "$INSTALL_DIR"
    install -m 0755 "$BIN_SRC" "${INSTALL_DIR}/${BINARY}"
  fi
else
  mkdir -p "$INSTALL_DIR"
  install -m 0755 "$BIN_SRC" "${INSTALL_DIR}/${BINARY}"
fi

# ── Done ────────────────────────────────────────────────────────────
printf '\n'
ok "Installed ${WHITE}sensai-cli ${VERSION}${RESET} to ${GOLD}${INSTALL_DIR}/${BINARY}${RESET}"

# Remind user to add to PATH if needed.
case ":${PATH:-}:" in
  *":${INSTALL_DIR}:"*) ;;
  *)
    printf '\n'
    dim "${INSTALL_DIR} is not in your PATH."
    dim "Use sensai-cli in this terminal now:"
    printf '  %sexport PATH="%s:$PATH"%s\n' "$WHITE" "$INSTALL_DIR" "$RESET"
    dim "Then run:"
    printf '  %ssensai-cli auth login%s\n' "$WHITE" "$RESET"
    dim "Add the export line to your shell profile to make it permanent."
    ;;
esac

printf '\n'
