#!/usr/bin/env bash
#
# Abstrax convenience installer.
#
# This script installs the Abstrax CLI by performing the same basic steps as
# the manual release archive instructions in the documentation:
#
#   - detect the server architecture
#   - find the latest GitHub release
#   - download the correct archive from GitHub
#   - download the published SHA-256 checksums file
#   - verify the archive with sha256sum
#   - extract the binary
#   - install it to /usr/local/bin/abstrax
#
# It does not change shell profiles, install dependencies, start services, or
# collect telemetry. It does nothing beyond installing the binary.
#
# If you prefer to see every step yourself, follow the manual release archive
# instructions in the documentation at:
#   https://useabstrax.com/docs/getting-started
#
set -euo pipefail

REPO="useabstrax/abstrax"
INSTALL_DIR="/usr/local/bin"
BINARY_NAME="abstrax"

info() {
    printf '==> %s\n' "$1"
}

error() {
    printf 'Error: %s\n' "$1" >&2
    exit 1
}

# --- Pre-flight checks -------------------------------------------------------

# Abstrax targets Linux servers only.
if [ "$(uname -s)" != "Linux" ]; then
    error "Abstrax only supports Linux. Detected: $(uname -s)"
fi

# Require the commands this script depends on.
for cmd in wget grep sed tar sha256sum uname; do
    if ! command -v "$cmd" >/dev/null 2>&1; then
        error "Required command '$cmd' was not found. Please install it and try again."
    fi
done

# Determine how to escalate privileges for the final move into INSTALL_DIR.
SUDO=""
if [ "$(id -u)" -ne 0 ]; then
    if command -v sudo >/dev/null 2>&1; then
        SUDO="sudo"
    else
        error "This script needs root privileges to install to ${INSTALL_DIR}. Re-run with sudo."
    fi
fi

# --- Architecture detection --------------------------------------------------

RAW_ARCH="$(uname -m)"
case "$RAW_ARCH" in
    x86_64)
        ARCH="amd64"
        ;;
    aarch64 | arm64)
        ARCH="arm64"
        ;;
    *)
        error "Unsupported architecture: ${RAW_ARCH}. Abstrax supports x86_64 (amd64) and aarch64/arm64."
        ;;
esac

info "Detected architecture: ${RAW_ARCH} (${ARCH})"

# --- Resolve the latest release ----------------------------------------------

info "Finding the latest Abstrax release..."

TAG="$(wget -qO- "https://api.github.com/repos/${REPO}/releases/latest" \
    | grep '"tag_name":' \
    | sed -E 's/.*"tag_name": *"([^"]+)".*/\1/')"

if [ -z "${TAG:-}" ]; then
    error "Could not determine the latest release tag from the GitHub API."
fi

# Release tags use a leading "v"; the filenames omit it.
VERSION="$(printf '%s' "$TAG" | sed 's/^v//')"

info "Latest version: ${VERSION}"

# --- Download ----------------------------------------------------------------

ARCHIVE="abstrax_${VERSION}_linux_${ARCH}.tar.gz"
CHECKSUMS="abstrax_${VERSION}_checksums.txt"
BASE_URL="https://github.com/${REPO}/releases/download/v${VERSION}"
ARCHIVE_URL="${BASE_URL}/${ARCHIVE}"
CHECKSUMS_URL="${BASE_URL}/${CHECKSUMS}"

# Work in a temporary directory and always clean it up.
TMP_DIR="$(mktemp -d)"
cleanup() {
    rm -rf "$TMP_DIR"
}
trap cleanup EXIT

info "Downloading binary from: ${ARCHIVE_URL}"
wget -q -O "${TMP_DIR}/${ARCHIVE}" "$ARCHIVE_URL" \
    || error "Failed to download the release archive from ${ARCHIVE_URL}"

info "Downloading checksums from: ${CHECKSUMS_URL}"
wget -q -O "${TMP_DIR}/${CHECKSUMS}" "$CHECKSUMS_URL" \
    || error "Failed to download the checksums file from ${CHECKSUMS_URL}"

# --- Verify ------------------------------------------------------------------

info "Verifying the archive with SHA-256..."
(
    cd "$TMP_DIR"
    # Only verify the archive we downloaded, not every entry in the file.
    grep " ${ARCHIVE}\$" "$CHECKSUMS" | sha256sum -c -
) || error "Checksum verification failed. Aborting before install."

info "Checksum verified."

# --- Extract and install -----------------------------------------------------

info "Extracting the binary..."
tar -xzf "${TMP_DIR}/${ARCHIVE}" -C "$TMP_DIR"

if [ ! -f "${TMP_DIR}/${BINARY_NAME}" ]; then
    error "The '${BINARY_NAME}' binary was not found in the archive."
fi

chmod +x "${TMP_DIR}/${BINARY_NAME}"

info "Installing to ${INSTALL_DIR}/${BINARY_NAME}"
$SUDO mkdir -p "$INSTALL_DIR"
$SUDO mv "${TMP_DIR}/${BINARY_NAME}" "${INSTALL_DIR}/${BINARY_NAME}"

# --- Report ------------------------------------------------------------------

info "Installed version:"
"${INSTALL_DIR}/${BINARY_NAME}" version || true

printf '\n'
printf 'Abstrax installed successfully.\n'
printf 'Run: abstrax --help\n'
printf 'Then: abstrax doctor\n'
