#!/usr/bin/env bash
#
# Fetch Labtris and hand off to the real installer.
#
#   curl -fsSL https://labtris.com/install | sudo bash
#
# Everything hard lives in packaging/install-labtris.sh — this script only
# has to get that far. Kept tiny on purpose: a curl-to-bash script that
# is doing anything clever is a script nobody reads before they run it.
#
# Override any of these on the command line:
#
#   sudo LABTRIS_TOKEN=github_pat_… bash -c "$(curl -fsSL labtris.com/install)"
#   sudo LABTRIS_BRANCH=some-topic bash -c ...
#   sudo LABTRIS_REPO=https://github.com/labtris/labtris.git bash -c ...
#   sudo LABTRIS_PREFIX=/srv/labtris bash -c ...
#   sudo LABTRIS_FORCE_OS=1 bash -c ...           # try on another distribution
#
set -euo pipefail

REPO=${LABTRIS_REPO:-https://github.com/labtris/labtris.git}
BRANCH=${LABTRIS_BRANCH:-main}
PREFIX=${LABTRIS_PREFIX:-/opt/labtris}
FORCE_OS=${LABTRIS_FORCE_OS:-0}
# The repository is private. A token from your access invitation goes in
# LABTRIS_TOKEN (GH_TOKEN and GITHUB_TOKEN are read too, for people who
# already have one in the environment). It is sent as a header on this
# clone only — nothing is written into $PREFIX/.git/config, so the token
# does not outlive the command that used it.
TOKEN=${LABTRIS_TOKEN:-${GH_TOKEN:-${GITHUB_TOKEN:-}}}
GIT=(git)
if [ -n "$TOKEN" ]; then
  GIT=(git -c "http.https://github.com/.extraheader=Authorization: basic $(printf 'x-access-token:%s' "$TOKEN" | base64 | tr -d '\n')")
fi

say() { printf '\n\033[1;36m==>\033[0m %s\n' "$*"; }
die() { printf '\033[1;31mERROR:\033[0m %s\n' "$*" >&2; exit 1; }

[ "$(id -u)" -eq 0 ] || die "run this as root (\`sudo bash\`, or pipe into \`sudo bash\`)"

# The native installer targets Ubuntu, because packages.txt is a list of apt
# package names. 24.04 and 26.04 are both supported and both tested. Refusing
# loudly rather than failing on a missing package six minutes in is the polite
# thing to do.
#
# 26.04 is supported. It was refused here until both blockers were fixed:
# guacd, which Ubuntu stopped packaging after noble and which
# packaging/build-guacd.sh now builds from source, and python3.12, which
# resolute does not package at all — packages.txt now names the
# distribution's own python3, and pyproject accepts 3.12 through 3.14.
#
# A correction worth recording, because it was committed wrong: an earlier
# version of this comment claimed python3.12 was available on resolute and
# only python3.12-venv was missing. That came from a package-search page and
# is false. `apt-cache policy python3.12` on resolute reports no candidate at
# all. Checked with apt on the release itself, which is the only source that
# settles it.
#
# The one real gap on 26.04 is RDP: guacd 1.6.0 does not build against
# FreeRDP 3, the only FreeRDP resolute has, so VNC, SSH and telnet consoles
# work there and RDP does not. Not a reason to refuse the install — it is a
# reason to say so, which the installer does in its closing summary.
if [ "$FORCE_OS" != 1 ]; then
  . /etc/os-release 2>/dev/null || true
  case "${ID:-}:${VERSION_ID:-}" in
    ubuntu:24.04|ubuntu:26.04) : ;;
    *)
    die "this installer wants Ubuntu 24.04 or 26.04; found ${PRETTY_NAME:-unknown}.
       The container install runs on any distribution with Docker:
         https://docs.labtris.com/reference/docker
       Set LABTRIS_FORCE_OS=1 to try anyway (nothing about the rest is
       Ubuntu-specific, but the package set is apt and Ubuntu package names)."
    ;;
  esac
  if [ "$(uname -m)" != x86_64 ]; then
    die "amd64 (x86_64) only — found $(uname -m). Set LABTRIS_FORCE_OS=1 to try."
  fi
fi

# Not a gate. Everything in Labtris runs on any kernel this OS ships —
# except soft-RoCE, which needs the per-namespace UDP 4791 socket that
# rdma_rxe gained in 7.1. Saying so here, before a five-minute install,
# beats letting someone discover it when an ib_send_bw moves zero bytes
# and prints no error. The installer repeats it in the closing summary.
KREL=$(uname -r)
case "${KREL%%.*}" in
  ''|*[!0-9]*) : ;;                       # unparseable — say nothing
  *)
    # No dot means no minor: without this a bare "7" parses as 7.7.
    _kmaj=${KREL%%.*}
    case "$KREL" in *.*) _krest=${KREL#*.}; _kmin=${_krest%%.*} ;; *) _kmin=0 ;; esac
    case "$_kmin" in ''|*[!0-9]*) _kmin=0 ;; esac
    if [ "$_kmaj" -lt 7 ] || { [ "$_kmaj" -eq 7 ] && [ "$_kmin" -lt 1 ]; }; then
      say "Note: kernel $KREL is below 7.1, so the RDMA lab will start and
    move no data. Every other lab, Ultra Ethernet included, is unaffected.
    https://labtris.com/install/guide#rdma-kernel"
    fi
    ;;
esac

say "Installing git, curl, ca-certificates (needed to clone)"
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y --no-install-recommends git curl ca-certificates

say "Fetching Labtris to $PREFIX (branch: $BRANCH)"
if [ -d "$PREFIX/.git" ]; then
  "${GIT[@]}" -C "$PREFIX" fetch --depth 1 origin "$BRANCH"
  git -C "$PREFIX" checkout -f FETCH_HEAD
else
  # --depth 1: the installer needs the tree, not the history.
  GIT_TERMINAL_PROMPT=0 "${GIT[@]}" clone --depth 1 --branch "$BRANCH" "$REPO" "$PREFIX" \
    || die "could not clone $REPO. It is a private repository: set LABTRIS_TOKEN to the
       token from your access invitation, or ask for one at contact@labtris.com."
fi

INSTALLER="$PREFIX/packaging/install-labtris.sh"
[ -x "$INSTALLER" ] || die "$INSTALLER is missing or not executable — corrupt clone?"

say "Handing off to $INSTALLER"
exec "$INSTALLER" --branch "$BRANCH" --source "$PREFIX"
