#!/usr/bin/env bash
set -euo pipefail

# Hermes FleetOps remote Tailscale deployment script for Ubuntu/Debian-like Linux.
# Supports dry-run validation without sudo/root changes.
# Real install requires root privileges or sudo and a Tailscale auth key.

MODE="install"
AUTHKEY=""
HOSTNAME_OVERRIDE=""
ACCEPT_ROUTES="false"
SSH_ENABLE="false"
DIAG_USER=""
CONTROL_PUBKEY=""
INSTALL_DIAG="true"

log(){ printf '[%s] %s\n' "$(date -Is 2>/dev/null || date)" "$*"; }
err(){ printf '[ERROR] %s\n' "$*" >&2; }
usage(){
  cat <<'EOF'
Usage:
  hermes-remote-tailscale-deploy.sh --dry-run
  sudo hermes-remote-tailscale-deploy.sh --authkey tskey-auth-... [options]

Options:
  --dry-run                  Validate platform, commands, repo URL, and planned actions only.
  --authkey KEY              Tailscale reusable/ephemeral/preauth auth key. Required for install unless already logged in.
  --hostname NAME            Tailscale node hostname override.
  --accept-routes true|false Whether to accept advertised routes. Default false.
  --ssh true|false           Whether to enable Tailscale SSH. Default false.
  --diag-user USER           Optional dedicated diagnostics user to create/update.
  --control-pubkey KEY       SSH public key to authorize for diag-user, or current user if diag-user omitted.
  --no-diag                  Do not install /opt/hermes-remote/diagnose.sh.
  -h|--help                  Show help.

Security notes:
  - Do not commit auth keys into this script.
  - Prefer ephemeral/preauthorized tagged keys and narrow Tailnet ACLs.
EOF
}

while [ $# -gt 0 ]; do
  case "$1" in
    --dry-run) MODE="dry-run"; shift ;;
    --authkey) AUTHKEY="${2:-}"; shift 2 ;;
    --hostname) HOSTNAME_OVERRIDE="${2:-}"; shift 2 ;;
    --accept-routes) ACCEPT_ROUTES="${2:-false}"; shift 2 ;;
    --ssh) SSH_ENABLE="${2:-false}"; shift 2 ;;
    --diag-user) DIAG_USER="${2:-}"; shift 2 ;;
    --control-pubkey) CONTROL_PUBKEY="${2:-}"; shift 2 ;;
    --no-diag) INSTALL_DIAG="false"; shift ;;
    -h|--help) usage; exit 0 ;;
    *) err "Unknown argument: $1"; usage; exit 2 ;;
  esac
done

if [ "$ACCEPT_ROUTES" != "true" ] && [ "$ACCEPT_ROUTES" != "false" ]; then err "--accept-routes must be true or false"; exit 2; fi
if [ "$SSH_ENABLE" != "true" ] && [ "$SSH_ENABLE" != "false" ]; then err "--ssh must be true or false"; exit 2; fi

log "Hermes remote Tailscale deploy starting mode=$MODE"
log "whoami=$(whoami 2>/dev/null || true) uid=$(id -u 2>/dev/null || true) hostname=$(hostname 2>/dev/null || true)"

if [ -r /etc/os-release ]; then . /etc/os-release; else ID=""; VERSION_CODENAME=""; fi
DISTRO="${ID:-unknown}"
CODENAME="${VERSION_CODENAME:-}"
log "detected distro=$DISTRO codename=$CODENAME pretty=${PRETTY_NAME:-unknown}"

case "$DISTRO:$CODENAME" in
  ubuntu:jammy|ubuntu:focal|ubuntu:noble|debian:bullseye|debian:bookworm|debian:trixie)
    REPO_BASE="https://pkgs.tailscale.com/stable/$DISTRO/$CODENAME"
    ;;
  *)
    if [ "$DISTRO" = "ubuntu" ] && [ -n "$CODENAME" ]; then REPO_BASE="https://pkgs.tailscale.com/stable/ubuntu/$CODENAME";
    elif [ "$DISTRO" = "debian" ] && [ -n "$CODENAME" ]; then REPO_BASE="https://pkgs.tailscale.com/stable/debian/$CODENAME";
    else err "Unsupported or unrecognized distro/codename: $DISTRO/$CODENAME"; exit 3; fi
    ;;
esac

need_cmd(){ command -v "$1" >/dev/null 2>&1 || { err "missing command: $1"; return 1; }; }
need_cmd sh
need_cmd curl
need_cmd apt-get
need_cmd systemctl || true

log "repo base would be: $REPO_BASE"
if [ "$MODE" = "dry-run" ]; then
  log "checking Tailscale package endpoints"
  curl -fsI "$REPO_BASE.noarmor.gpg" >/dev/null && log "OK: $REPO_BASE.noarmor.gpg" || { err "cannot reach gpg endpoint"; exit 4; }
  curl -fsI "$REPO_BASE.tailscale-keyring.list" >/dev/null && log "OK: $REPO_BASE.tailscale-keyring.list" || { err "cannot reach list endpoint"; exit 4; }
  if command -v tailscale >/dev/null 2>&1; then log "tailscale already present: $(command -v tailscale)"; tailscale version || true; else log "tailscale currently not installed"; fi
  if [ -n "$AUTHKEY" ]; then log "authkey provided: yes length=${#AUTHKEY}"; else log "authkey provided: no"; fi
  log "dry-run complete; no system changes made"
  exit 0
fi

if [ "$(id -u)" -ne 0 ]; then
  err "install mode must run as root. Re-run with sudo."
  exit 5
fi

if [ -z "$AUTHKEY" ] && ! tailscale status >/dev/null 2>&1; then
  err "--authkey is required when node is not already logged in"
  exit 6
fi

log "installing Tailscale apt repository"
install -d -m 0755 /usr/share/keyrings
curl -fsSL "$REPO_BASE.noarmor.gpg" -o /usr/share/keyrings/tailscale-archive-keyring.gpg
curl -fsSL "$REPO_BASE.tailscale-keyring.list" -o /etc/apt/sources.list.d/tailscale.list
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y tailscale
systemctl enable --now tailscaled

UP_ARGS=(up "--accept-routes=$ACCEPT_ROUTES" "--ssh=$SSH_ENABLE")
if [ -n "$AUTHKEY" ]; then UP_ARGS+=("--authkey=$AUTHKEY"); fi
if [ -n "$HOSTNAME_OVERRIDE" ]; then UP_ARGS+=("--hostname=$HOSTNAME_OVERRIDE"); fi
log "running tailscale up with authkey redacted"
tailscale "${UP_ARGS[@]}"

if [ -n "$DIAG_USER" ]; then
  log "creating/updating diagnostics user $DIAG_USER"
  if ! id "$DIAG_USER" >/dev/null 2>&1; then useradd -m -s /bin/bash "$DIAG_USER"; fi
  if [ -n "$CONTROL_PUBKEY" ]; then
    install -d -m 0700 -o "$DIAG_USER" -g "$DIAG_USER" "/home/$DIAG_USER/.ssh"
    touch "/home/$DIAG_USER/.ssh/authorized_keys"
    chown "$DIAG_USER:$DIAG_USER" "/home/$DIAG_USER/.ssh/authorized_keys"
    chmod 0600 "/home/$DIAG_USER/.ssh/authorized_keys"
    grep -qxF "$CONTROL_PUBKEY" "/home/$DIAG_USER/.ssh/authorized_keys" || printf '%s\n' "$CONTROL_PUBKEY" >> "/home/$DIAG_USER/.ssh/authorized_keys"
  fi
fi

if [ "$INSTALL_DIAG" = "true" ]; then
  log "installing root diagnostics script /opt/hermes-remote/diagnose.sh"
  install -d -m 0755 /opt/hermes-remote
  cat > /opt/hermes-remote/diagnose.sh <<'DIAG'
#!/usr/bin/env bash
set -euo pipefail
TS=$(date -u +%Y%m%dT%H%M%SZ)
HOST=$(hostname 2>/dev/null || echo unknown)
BASE="/tmp/hermes-root-diagnose-${HOST}-${TS}"
mkdir -p "$BASE"
run(){ name="$1"; shift; { echo "### $name"; echo "### command: $*"; "$@"; } >"$BASE/$name.txt" 2>&1 || true; }
run hostname hostname
run date date -Is
run uname uname -a
run os_release bash -lc 'cat /etc/os-release 2>/dev/null || true'
run uptime uptime
run last_reboot last reboot
run df df -hT
run free free -h
run lsblk lsblk -a
run mount mount
run ip_addr ip addr
run ip_route ip route
run ss_listen ss -lntup
run systemctl_failed systemctl --failed
run journal_boot journalctl -b --no-pager
run journal_prev journalctl -b -1 --no-pager
run journal_errors journalctl --since '14 days ago' -p warning..alert --no-pager
run dmesg dmesg -T
run tailscale_status bash -lc 'command -v tailscale >/dev/null && tailscale status || echo tailscale_not_installed'
run tailscale_netcheck bash -lc 'command -v tailscale >/dev/null && tailscale netcheck || true'
run smartctl_scan bash -lc 'command -v smartctl >/dev/null && smartctl --scan || echo smartctl_missing'
run pstore bash -lc 'ls -la /sys/fs/pstore 2>/dev/null && for f in /sys/fs/pstore/*; do [ -f "$f" ] && echo "--- $f" && head -200 "$f"; done || true'
OUT="/tmp/${BASE##*/}.tar.gz"
tar -C "$(dirname "$BASE")" -czf "$OUT" "$(basename "$BASE")"
echo "$OUT"
DIAG
  chmod 0755 /opt/hermes-remote/diagnose.sh
fi

log "final Tailscale status"
tailscale status || true
tailscale ip -4 || true
log "install complete"
