#!/usr/bin/env bash
# bootstrap/install — curl|bash bootstrap for https://boot.bgp.exchange/install
# Downloads the latest installer release, verifies checksum, extracts, and runs install.sh.
#
# Safe for a normal user with sudo:
#   curl -fsSL https://boot.bgp.exchange/install | bash
#   curl -fsSL https://boot.bgp.exchange/install | sudo bash

set -Eeuo pipefail

BOOT_BASE="${BGPEX_BOOT_BASE:-https://boot.bgp.exchange}"
API_BASE="${BGPEX_API_BASE:-https://api.boot.bgp.exchange}"
export API_BASE
CHANNEL="${BGPEX_INSTALLER_CHANNEL:-stable}"
INSTALL_ROOT="${BGPEX_INSTALL_ROOT:-/opt/bgpexchange/installer}"
TMP_DIR=""

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

log() { printf '[bgpex-boot] %s\n' "$*" >&2; }
die() { log "ERROR: $*"; exit 1; }

# ---------------------------------------------------------------------------
# Privilege: root, or sudo with preflight checks (before any system changes)
# ---------------------------------------------------------------------------
bootstrap_elevate() {
  if [[ "${EUID}" -eq 0 ]]; then
    return 0
  fi

  if [[ "${BGPEX_ALREADY_ELEVATED:-0}" == "1" ]]; then
    die "still not root after sudo re-exec (check sudoers)"
  fi

  log "Installer must run as root — checking sudo…"

  if ! command -v sudo >/dev/null 2>&1; then
    die "not root and sudo is not installed. Run:  curl -fsSL ${BOOT_BASE}/install | sudo bash"
  fi

  if sudo -n true >/dev/null 2>&1; then
    log "sudo: OK (passwordless or cached credentials)"
  else
    log "sudo: authenticating (password may be required)…"
    sudo -v || die "sudo authentication failed — your user needs sudo rights"
  fi

  local probe
  for probe in /etc /opt /var /run /usr/local/bin; do
    sudo test -d "${probe}" || die "sudo cannot access ${probe}"
  done
  sudo touch /etc/.bgpex-sudo-probe 2>/dev/null || die "sudo cannot write under /etc"
  sudo rm -f /etc/.bgpex-sudo-probe 2>/dev/null || true
  log "sudo: privilege checks passed — re-running bootstrap as root"

  # Piped curl|bash has no stable \$0; re-fetch under sudo and keep args/env.
  local -a env_args=(
    "BGPEX_ALREADY_ELEVATED=1"
    "DEBIAN_FRONTEND=noninteractive"
    "BGPEX_BOOT_BASE=${BOOT_BASE}"
    "BGPEX_API_BASE=${API_BASE}"
    "BGPEX_INSTALLER_CHANNEL=${CHANNEL}"
    "BGPEX_INSTALL_ROOT=${INSTALL_ROOT}"
  )
  local k
  for k in BGPEX_API_TOKEN BGPEX_INSTALLER_TARBALL_URL BGPEX_ROLE BGPEX_ASN BGPEX_HOSTNAME BGPEX_SITE; do
    if [[ -n "${!k:-}" ]]; then
      env_args+=("${k}=${!k}")
    fi
  done

  local arg_q=""
  if [[ $# -gt 0 ]]; then
    printf -v arg_q '%q ' "$@"
  fi

  exec sudo -E env "${env_args[@]}" bash -c \
    "curl -fsSL --connect-timeout 15 --max-time 120 '${BOOT_BASE}/install' | bash -s -- ${arg_q}"
}

bootstrap_elevate "$@"

export DEBIAN_FRONTEND=noninteractive
TMP_DIR="$(mktemp -d /tmp/bgpex-boot.XXXXXX)"

if ! command -v curl >/dev/null 2>&1; then
  apt-get update -y
  apt-get install -y --no-install-recommends curl ca-certificates
fi
command -v tar >/dev/null 2>&1 || apt-get install -y --no-install-recommends tar
command -v sha256sum >/dev/null 2>&1 || apt-get install -y --no-install-recommends coreutils
command -v rsync >/dev/null 2>&1 || apt-get install -y --no-install-recommends rsync || true
# Needed immediately by install.sh API discovery (before full package step)
command -v python3 >/dev/null 2>&1 || apt-get install -y --no-install-recommends python3
command -v jq >/dev/null 2>&1 || apt-get install -y --no-install-recommends jq || true

TARBALL_URL="${BGPEX_INSTALLER_TARBALL_URL:-${BOOT_BASE}/releases/${CHANNEL}/bgpexchange-installer-latest.tar.gz}"
SHA_URL="${TARBALL_URL}.sha256"

log "Downloading ${TARBALL_URL}"
curl -fsSL --connect-timeout 15 --max-time 120 -o "${TMP_DIR}/installer.tar.gz" "${TARBALL_URL}" \
  || die "download failed"

EXPECTED=""
if curl -fsSL --connect-timeout 10 --max-time 30 -o "${TMP_DIR}/installer.sha256" "${SHA_URL}"; then
  EXPECTED="$(awk '{print $1; exit}' "${TMP_DIR}/installer.sha256")"
fi

if [[ -n "${EXPECTED}" ]]; then
  ACTUAL="$(sha256sum "${TMP_DIR}/installer.tar.gz" | awk '{print $1}')"
  [[ "${ACTUAL}" == "${EXPECTED}" ]] || die "SHA-256 mismatch (got ${ACTUAL}, expected ${EXPECTED})"
  log "Checksum OK"
else
  log "WARNING: no checksum published at ${SHA_URL}; continuing without verification"
fi

mkdir -p "${INSTALL_ROOT}"
tar -xzf "${TMP_DIR}/installer.tar.gz" -C "${TMP_DIR}"
SRC="$(find "${TMP_DIR}" -maxdepth 3 -type f -name install.sh | head -n1 | xargs -r dirname)"
[[ -n "${SRC}" && -f "${SRC}/install.sh" ]] || die "install.sh missing from release archive"

# Atomic replace
rsync -a --delete --exclude '.git' "${SRC}/" "${INSTALL_ROOT}/" 2>/dev/null \
  || { rm -rf "${INSTALL_ROOT}.new"; mkdir -p "${INSTALL_ROOT}.new"; cp -a "${SRC}/." "${INSTALL_ROOT}.new/"; rm -rf "${INSTALL_ROOT}"; mv "${INSTALL_ROOT}.new" "${INSTALL_ROOT}"; }

chmod +x "${INSTALL_ROOT}/install.sh" "${INSTALL_ROOT}/repair.sh" \
  "${INSTALL_ROOT}/update.sh" "${INSTALL_ROOT}/uninstall.sh" \
  "${INSTALL_ROOT}/bin/"* "${INSTALL_ROOT}/services/"*.sh 2>/dev/null || true

# Symlink health tool
install -d /usr/local/bin
ln -sfn "${INSTALL_ROOT}/bin/bgpx-health" /usr/local/bin/bgpx-health

log "Launching installer from ${INSTALL_ROOT}"
exec "${INSTALL_ROOT}/install.sh" "$@"
