#!/usr/bin/env bash
# SPDX-License-Identifier: AGPL-3.0-or-later
# One-shot provisioning for the pvtcoms relay: updates, cleanup, latest kernel, full security
# hardening, Tor onion relay, and an end-to-end self-test. Run as root once:
#   ADMIN_IP=<your-admin-ip> bash provision.sh
# (Expects harden.sh, setup-relay.sh, and the relay binary `pvtcoms-relay` alongside this script.)
set -uo pipefail

HERE="$(cd "$(dirname "$0")" && pwd)"
ADMIN_IP="${ADMIN_IP:-}"
log() { printf '\033[1;36m[provision]\033[0m %s\n' "$*"; }
die() { printf '\033[1;31m[provision] %s\033[0m\n' "$*" >&2; exit 1; }
[ "$(id -u)" -eq 0 ] || die "run as root"

export DEBIAN_FRONTEND=noninteractive

# 1. Updates + upgrades --------------------------------------------------------
log "Updating + full-upgrading the system…"
apt-get update -y
apt-get -y full-upgrade

# 2. Latest kernel (24.04 HWE stack; 26.04 already ships a current GA kernel) ---
. /etc/os-release 2>/dev/null || true
log "OS: ${PRETTY_NAME:-unknown}"
if [ "${VERSION_ID:-}" = "24.04" ]; then
  log "Installing the HWE (latest) kernel stack…"
  apt-get install -y linux-generic-hwe-24.04 || true
fi

# 3. Remove what's not needed --------------------------------------------------
log "Removing unneeded packages (autoremove --purge; drop snapd on a headless relay)…"
if dpkg -l snapd 2>/dev/null | grep -q '^ii'; then
  systemctl stop snapd 2>/dev/null || true
  apt-get -y purge snapd || true
fi
apt-get -y autoremove --purge
apt-get -y clean

# 4. Security hardening (non-root sudo user + key-only SSH + UFW + fail2ban + sysctl + auto-updates)
log "Hardening the OS…"
RELAY_USER=pvtops bash "$HERE/harden.sh" || die "harden.sh failed"

# 4b. Allow-list the admin IP in fail2ban so a stray failure can't lock us out.
if [ -n "$ADMIN_IP" ]; then
  log "Allow-listing admin IP $ADMIN_IP in fail2ban…"
  printf '[DEFAULT]\nignoreip = 127.0.0.1/8 ::1 %s\n' "$ADMIN_IP" \
    > /etc/fail2ban/jail.d/00-ignoreip.local
  systemctl restart fail2ban 2>/dev/null || true
fi

# 4c. We deliberately KEEP the root password (your console break-glass). harden.sh already turned OFF
#     SSH password auth, so the chat-exposed password is useless over SSH; it stays valid only for the
#     Contabo web console (panel-gated). Change it in the panel at your convenience.
log "Root password kept for console break-glass; SSH password auth is OFF."

# 5. Tor onion + relay daemon + access key ------------------------------------
log "Installing Tor + the oblivious relay…"
BIN_SRC="$HERE/pvtcoms-relay" bash "$HERE/setup-relay.sh" || die "setup-relay.sh failed"

# 6. End-to-end self-test against the LOCAL relay (deposit → pull through the daemon) ----
log "Self-testing the relay (deposit + pull via the access key + PoW)…"
sleep 2
ENVF=/etc/pvtcoms-relay.env
KEY="$(grep '^PVTCOMS_RELAY_KEY=' "$ENVF" | cut -d= -f2)"
POW="$(grep '^PVTCOMS_RELAY_POW=' "$ENVF" | cut -d= -f2)"
PORT="${RELAY_PORT:-9911}"
TESTPASS="__provision_selftest__"
SELFTEST_OK=0
if [ -n "$KEY" ]; then
  PVTCOMS_RELAY_KEY="$KEY" PVTCOMS_RELAY_POW="$POW" \
    /usr/local/bin/pvtcoms-relay send "127.0.0.1:${PORT}" "$TESTPASS" "relay selftest ok" >/dev/null 2>&1
  OUT="$(PVTCOMS_RELAY_KEY="$KEY" PVTCOMS_RELAY_POW="$POW" \
    /usr/local/bin/pvtcoms-relay recv "127.0.0.1:${PORT}" "$TESTPASS" 2>/dev/null)"
  echo "$OUT" | grep -q "relay selftest ok" && SELFTEST_OK=1
fi

# 7. Summary -------------------------------------------------------------------
echo
echo "==================== pvtcoms relay — provisioning complete ===================="
echo " OS:        ${PRETTY_NAME:-?}   kernel: $(uname -r)"
echo " Relay:     $(systemctl is-active pvtcoms-relay 2>/dev/null) (systemd, sandboxed, 127.0.0.1:${PORT})"
echo " Tor:       $(systemctl is-active tor 2>/dev/null)"
echo " Firewall:  $(ufw status | head -1)"
echo " Self-test: $([ "$SELFTEST_OK" = 1 ] && echo 'PASS ✓ (deposit+pull round-trip)' || echo 'FAILED ✗ — check journalctl -u pvtcoms-relay')"
echo
echo " RELAY ONION (bake into the app):"
echo "     $(cat /var/lib/tor/pvtcoms-relay/hostname 2>/dev/null || echo '<pending — check after Tor publishes>')"
echo " ACCESS KEY (give to invited members only):"
echo "     ${KEY}"
echo "==============================================================================="
[ "$SELFTEST_OK" = 1 ] || exit 1
