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

# Rizoma Relay Setup (0.9.250.95)
#
# Enrolls a new relay host into the Rizoma mesh via the
# dashboard's Add Relay flow. Mirrors the hardened Add Peer
# (agent.sh) mechanics:
#
#   1. Signals /v1/install/start so the dashboard's modal moves
#      out of "waiting".
#   2. Installs rizoma-relay from the package repo (apt or dnf,
#      detected automatically).
#   3. Prompts for the one-time auth_key (60s TTL, single-use,
#      minted by the dashboard) — the key is never passed on the
#      command line, so it never lands in shell history or
#      process listings.
#   4. Exchanges the auth_key at /v1/relay/enroll-exchange —
#      the coordinator creates the relay row and returns
#      relay_id + relay_secret.
#   5. Writes /etc/rizoma/relay.env + relay.state and starts
#      rizoma-relay.service. From here the relay is a normal
#      first-class citizen (heartbeats, health checks, cert
#      renewal, rebalancing).
#
# Usage (the command the Add Relay modal renders):
#   curl -fsSL https://COORDINATOR/install/relay-setup.sh | bash -s -- \
#     --coordinator-url 'https://COORDINATOR' \
#     --session-id 'SESSION' \
#     --name 'relay-fra-1' \
#     --public-addr 'relay.example.com:4243'  (optional — auto-detected when omitted) \
#     --region 'eu-central'
#
# The script also works fully interactively without arguments
# (prompts for everything).

RELAY_NAME=""
PUBLIC_ADDR=""
REGION="default"
COORDINATOR_URL=""
INSTALL_SESSION_ID=""
AUTH_KEY=""
MAX_CONNECTIONS=10000
# 0.9.250.94: the script configures the package repo itself, the
# same way agent.sh (Add Peer) does — .93 assumed the repo was
# already configured on the host and died at the first apt
# install on any fresh box.
REPO_URL="${REPO_URL:-https://repo.rizomarl.com/mesh}"
CHANNEL="${CHANNEL:-stable}"
STATE_PATH="/var/lib/rizoma/relay/relay.state"
ENV_PATH="/etc/rizoma/relay.env"
LOG_FILE="/var/log/rizoma-relay-setup.log"

log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE" >&2; }
die() { log "ERROR: $*"; exit 1; }
json_escape() { printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'; }

mkdir -p "$(dirname "$LOG_FILE")" 2>/dev/null || LOG_FILE="/tmp/rizoma-relay-setup.log"
touch "$LOG_FILE" 2>/dev/null || true

if [[ "$(id -u)" -ne 0 ]]; then
  echo "error: relay setup must run as root (sudo)" >&2
  exit 1
fi

while [[ $# -gt 0 ]]; do
  case "$1" in
    --coordinator-url) COORDINATOR_URL="${2:-}"; shift 2 ;;
    --session-id) INSTALL_SESSION_ID="${2:-}"; shift 2 ;;
    --name) RELAY_NAME="${2:-}"; shift 2 ;;
    --public-addr) PUBLIC_ADDR="${2:-}"; shift 2 ;;
    --region) REGION="${2:-}"; shift 2 ;;
    --auth-key) AUTH_KEY="${2:-}"; shift 2 ;;
    --max-connections) MAX_CONNECTIONS="${2:-10000}"; shift 2 ;;
    *) echo "unknown argument: $1" >&2; shift ;;
  esac
done

# --- Interactive fallbacks (non-modal usage) ---
if [[ -z "$COORDINATOR_URL" ]]; then
  read -r -p "Coordinator URL (https://mesh.example.com): " COORDINATOR_URL
fi
COORDINATOR_URL="${COORDINATOR_URL%/}"
[[ -n "$COORDINATOR_URL" ]] || die "coordinator URL is required"
[[ "$COORDINATOR_URL" == http* ]] || die "coordinator URL must start with http(s)://"

# -----------------------------------------------------------------
# Public address auto-detection (0.9.250.93): the dashboard no
# longer asks the operator for an IP/port — the script detects
# the address the same way the platform does for peers. Order:
#   1. --public-addr flag (explicit override, scripted use)
#   2. egress IP via public echo services (on most boxes the
#      egress IP is the publicly reachable one)
#   3. default-route source IP (ip route get)
#   4. interactive prompt (last resort, non-modal usage only)
# -----------------------------------------------------------------
detect_public_addr() {
  local svc ip
  for svc in "https://api.ipify.org" "https://ifconfig.me/ip" "https://icanhazip.com"; do
    ip="$(curl -fsS --max-time 5 "$svc" 2>/dev/null | tr -d '[:space:]')"
    if [[ -n "$ip" ]]; then
      printf '%s' "$ip"
      return 0
    fi
  done
  if command -v ip >/dev/null 2>&1; then
    ip="$(ip route get 1.1.1.1 2>/dev/null | awk '{for(i=1;i<=NF;i++) if($i=="src"){print $(i+1); exit}}')"
    if [[ -n "$ip" ]]; then
      printf '%s' "$ip"
      return 0
    fi
  fi
  return 1
}

# Bare detected addresses get the default QUIC port; bare IPv6
# is bracketed so host:port parsing succeeds server-side.
format_public_addr() {
  local addr="$1" colons
  [[ -z "$addr" ]] && { printf '%s' ""; return 0; }
  colons="$(printf '%s' "$addr" | tr -cd ':' | wc -c)"
  if [[ "$colons" -eq 0 ]]; then
    addr="${addr}:4243"
  elif [[ "$colons" -ge 2 && "$addr" != \[* ]]; then
    addr="[${addr}]:4243"
  fi
  printf '%s' "$addr"
}

if [[ -z "$PUBLIC_ADDR" ]]; then
  log "Detecting public address..."
  PUBLIC_ADDR="$(detect_public_addr)"
  if [[ -n "$PUBLIC_ADDR" ]]; then
    log "Detected: $PUBLIC_ADDR"
  else
    log "Auto-detection failed (no egress route info available)"
  fi
fi
if [[ -z "$PUBLIC_ADDR" ]]; then
  read -r -p "Public QUIC address (host:port, default port 4243): " PUBLIC_ADDR
fi
[[ -n "$PUBLIC_ADDR" ]] || die "public address is required (auto-detection failed and no address given)"
PUBLIC_ADDR="$(format_public_addr "$PUBLIC_ADDR")"
if [[ -z "$RELAY_NAME" ]]; then
  RELAY_NAME="relay-$(hostname)"
fi

log "Rizoma relay setup starting"
log "  coordinator:  $COORDINATOR_URL"
log "  public addr:  $PUBLIC_ADDR"
log "  name:         $RELAY_NAME"
log "  region:       $REGION"

# -----------------------------------------------------------------
# Install lifecycle handshake (Add Relay modal state machine)
# -----------------------------------------------------------------
install_lifecycle_call() {
  local endpoint="$1"
  local body="$2"
  [[ -z "$INSTALL_SESSION_ID" ]] && return 0
  command -v curl >/dev/null 2>&1 || return 0
  local url="${COORDINATOR_URL%/}/v1/install/${endpoint}"
  curl -sS --max-time 10 \
    -H "Content-Type: application/json" \
    -X POST \
    --data "$body" \
    "$url" >/dev/null 2>&1 || true
}

install_lifecycle_start() {
  install_lifecycle_call "start" "{\"session_id\":\"$(json_escape "$INSTALL_SESSION_ID")\",\"hostname\":\"$(json_escape "$(hostname)")\",\"created_via\":\"relay_setup\"}"
}

install_lifecycle_ready() {
  install_lifecycle_call "ready" "{\"session_id\":\"$(json_escape "$INSTALL_SESSION_ID")\"}"
}

install_lifecycle_complete() {
  local node_id="$1"
  install_lifecycle_call "complete" "{\"session_id\":\"$(json_escape "$INSTALL_SESSION_ID")\",\"node_id\":\"$(json_escape "$node_id")\"}"
}

install_lifecycle_failed() {
  local reason="$1"
  install_lifecycle_call "failed" "{\"session_id\":\"$(json_escape "$INSTALL_SESSION_ID")\",\"reason\":\"$(json_escape "$reason")\"}"
}

install_lifecycle_start

# -----------------------------------------------------------------
# Package installation (jq is a hard dependency for parsing the
# exchange response — same convention as agent.sh). The deb's
# postinst does NOT create the rizoma-relay system user (only
# the full-node install.sh does, via setup-systemd-users.sh) —
# create it here, idempotently, with the same flags
# (packaging/systemd/setup-systemd-users.sh).
# -----------------------------------------------------------------
# Repo bootstrap — ported from agent.sh (install_apt_keyring +
# sources.list / rpm key), so a FRESH host with no rizoma repo
# configured installs cleanly. Idempotent: re-running on a host
# that already has the repo just skips re-adding.
repo_already_configured() {
  if command -v apt-get >/dev/null 2>&1; then
    [[ -f /etc/apt/sources.list.d/rizoma.list ]]
  elif command -v dnf >/dev/null 2>&1; then
    [[ -f /etc/yum.repos.d/rizoma.repo ]]
  else
    false
  fi
}

install_apt_keyring() {
  local tmp_key tmp_out
  tmp_key="$(mktemp /tmp/rizoma-keyring.XXXXXX)"
  if ! curl -fsSL --max-time 15 "$REPO_URL/keys/rizoma-archive-keyring.gpg" -o "$tmp_key"; then
    rm -f "$tmp_key"
    die "could not fetch the rizoma repo keyring from $REPO_URL — is the repo reachable from this host?"
  fi
  if grep -q "BEGIN PGP PUBLIC KEY BLOCK" "$tmp_key"; then
    tmp_out="$(mktemp /tmp/rizoma-keyring-out.XXXXXX)"
    if ! gpg --batch --yes --dearmor -o "$tmp_out" "$tmp_key" 2>/dev/null; then
      rm -f "$tmp_key" "$tmp_out"
      die "gpg dearmor of the rizoma keyring failed"
    fi
    install -m 0644 "$tmp_out" /usr/share/keyrings/rizoma-archive-keyring.gpg
    rm -f "$tmp_out"
  else
    install -m 0644 "$tmp_key" /usr/share/keyrings/rizoma-archive-keyring.gpg
  fi
  rm -f "$tmp_key"
}

bootstrap_repo() {
  if command -v apt-get >/dev/null 2>&1; then
    mkdir -p /usr/share/keyrings
    install_apt_keyring
    printf 'deb [signed-by=/usr/share/keyrings/rizoma-archive-keyring.gpg] %s/apt/%s ./\n' "$REPO_URL" "$CHANNEL" > /etc/apt/sources.list.d/rizoma.list
  elif command -v dnf >/dev/null 2>&1; then
    mkdir -p /etc/pki/rpm-gpg /etc/yum.repos.d
    local tmp_key
    tmp_key="$(mktemp /tmp/rizoma-rpm-key.XXXXXX)"
    if ! curl -fsSL --max-time 15 "$REPO_URL/keys/RPM-GPG-KEY-rizoma" -o "$tmp_key"; then
      rm -f "$tmp_key"
      die "could not fetch the rizoma RPM key from $REPO_URL — is the repo reachable from this host?"
    fi
    install -m 0644 "$tmp_key" /etc/pki/rpm-gpg/RPM-GPG-KEY-rizoma
    rm -f "$tmp_key"
    printf '[rizoma]\nname=Rizoma\nbaseurl=%s/dnf/%s/\nenabled=1\ngpgcheck=1\ngpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-rizoma\n' "$REPO_URL" "$CHANNEL" > /etc/yum.repos.d/rizoma.repo
  else
    die "neither apt-get nor dnf found on this host"
  fi
}

install_package() {
  if command -v apt-get >/dev/null 2>&1; then
    export DEBIAN_FRONTEND=noninteractive
    if ! repo_already_configured; then
      log "Configuring rizoma package repo (first run on this host)..."
      bootstrap_repo
    fi
    # Show apt's real error on failure — the .93 version piped
    # it to /dev/null and the operator got a bare "failed".
    if ! apt-get update -qq; then
      log "apt-get update reported issues (continuing — repo metadata may be partially cached)"
    fi
    if ! apt-get install -y rizoma-relay jq; then
      die "apt install rizoma-relay jq failed — see the apt output above"
    fi
  elif command -v dnf >/dev/null 2>&1; then
    if ! repo_already_configured; then
      log "Configuring rizoma package repo (first run on this host)..."
      bootstrap_repo
    fi
    if ! dnf install -y rizoma-relay jq; then
      die "dnf install rizoma-relay jq failed — see the dnf output above"
    fi
  else
    die "neither apt-get nor dnf found on this host"
  fi
}

if ! id -u rizoma-relay >/dev/null 2>&1; then
  log "Creating rizoma-relay system user..."
  useradd --system --no-create-home --shell /usr/sbin/nologin rizoma-relay || die "failed to create rizoma-relay system user"
fi

if ! command -v rizoma-relay >/dev/null 2>&1 || ! command -v jq >/dev/null 2>&1; then
  log "Installing rizoma-relay + jq packages..."
  install_package
fi
command -v rizoma-relay >/dev/null 2>&1 || die "rizoma-relay binary not found after install"
command -v jq >/dev/null 2>&1 || die "jq not found after install"

# -----------------------------------------------------------------
# Auth key: prompt AFTER install (the dashboard is now in
# "ready" state — this is the exact hardened ordering from the
# Add Peer flow: /v1/install/ready, then prompt).
#
# 0.9.250.95: the prompt now reads from /dev/tty when stdin is
# the curl pipe (`curl URL | bash`), the same fix agent.sh got
# in 0.9.250.2 — the .94 script checked `[[ -t 0 ]]`, which is
# false under the pipe, so the modal flow DIED with "auth key
# required" instead of prompting while the dashboard waited at
# the Generate screen.
# -----------------------------------------------------------------
install_lifecycle_ready

prompt_for_auth_key() {
  if [[ -n "$AUTH_KEY" ]]; then
    return 0
  fi
  if [[ -n "${RIZOMA_RELAY_AUTH_KEY:-}" ]]; then
    AUTH_KEY="$RIZOMA_RELAY_AUTH_KEY"
    return 0
  fi

  # stdin TTY (bash relay-setup.sh) → read from fd 0; stdin is
  # the curl pipe → read from /dev/tty (the operator's
  # terminal); neither (cron) → clear error with hints.
  local read_source="stdin"
  if [[ ! -t 0 ]]; then
    if [[ -r /dev/tty ]]; then
      read_source="/dev/tty"
    else
      echo "" >&2
      echo "  ERROR: --auth-key (or RIZOMA_RELAY_AUTH_KEY env) is required when" >&2
      echo "  stdin is not a TTY and no controlling terminal is available" >&2
      echo "  hint: pass --auth-key 'ak_XXXXXXXXXXXXXXXX' to the install command" >&2
      echo "  hint: or set RIZOMA_RELAY_AUTH_KEY before running" >&2
      return 1
    fi
  fi

  echo ""
  echo "  ====================================================================="
  echo "  ONE-TIME AUTH KEY REQUIRED"
  echo "  ====================================================================="
  echo "  1. Switch to the dashboard (in your browser) — leave this SSH"
  echo "     session open and switch back here AFTER step 4."
  echo "  2. The Add Relay modal should now show the key step."
  echo "  3. Click the 'Generate one-time key' button — the key appears"
  echo "     with a 60s countdown. Copy it (the copy button next to it)."
  echo "  4. Switch back here and paste the key at the prompt below."
  echo "  ====================================================================="
  echo ""
  echo "  The key is 19 characters, starts with 'ak_'."
  echo ""

  local raw=""
  if [[ "$read_source" == "/dev/tty" ]]; then
    read -r -t 180 -p "  auth_key> " raw < /dev/tty || {
      local rc=$?
      echo "" >&2
      if [[ $rc -eq 142 ]]; then
        echo "  ERROR: auth_key prompt timed out after 180s — the dashboard session has expired" >&2
        echo "  hint: restart the install from the dashboard's Add Relay modal" >&2
      else
        echo "  ERROR: could not read auth_key from /dev/tty (rc=$rc)" >&2
      fi
      return 1
    }
  else
    read -r -t 180 -p "  auth_key> " raw || {
      local rc=$?
      echo "" >&2
      if [[ $rc -eq 142 ]]; then
        echo "  ERROR: auth_key prompt timed out after 180s — the dashboard session has expired" >&2
        echo "  hint: restart the install from the dashboard's Add Relay modal" >&2
      else
        echo "  ERROR: could not read auth_key (rc=$rc)" >&2
      fi
      return 1
    }
  fi
  raw="${raw// /}"
  if [[ ! "$raw" =~ ^ak_[A-Z0-9]{16}$ ]]; then
    echo "" >&2
    echo "  ERROR: auth_key format is invalid (expected 'ak_' + 16 chars from [A-Z0-9])" >&2
    echo "  hint: open the dashboard's Add Relay modal, click Generate," >&2
    echo "  copy the key, and paste it here." >&2
    return 1
  fi
  AUTH_KEY="$raw"
  return 0
}

prompt_for_auth_key || install_lifecycle_failed "auth_key_prompt_failed"
[[ -n "$AUTH_KEY" ]] || die "auth key is required"

# -----------------------------------------------------------------
# Enrollment exchange: auth_key → relay_id + relay_secret
# -----------------------------------------------------------------
log "Enrolling relay with coordinator..."
EXCHANGE_BODY="$(cat <<EOF
{"auth_key":"$(json_escape "$AUTH_KEY")","name":"$(json_escape "$RELAY_NAME")","public_addr":"$(json_escape "$PUBLIC_ADDR")","region":"$(json_escape "$REGION")","version":"relay-setup-0.9.250.95","max_connections":$(json_escape "$MAX_CONNECTIONS")}
EOF
)"
EXCHANGE_RESP="$(mktemp /tmp/rizoma-relay-exchange.XXXXXX)"
trap 'rm -f "$EXCHANGE_RESP"' EXIT
HTTP_CODE="$(curl -sS --max-time 15 \
  -H "Content-Type: application/json" \
  -X POST \
  -w '%{http_code}' \
  --data "$EXCHANGE_BODY" \
  "${COORDINATOR_URL%/}/v1/relay/enroll-exchange" \
  -o "$EXCHANGE_RESP" 2>/dev/null)" || HTTP_CODE=000

if [[ "$HTTP_CODE" != "201" && "$HTTP_CODE" != "200" ]]; then
  install_lifecycle_failed "exchange_failed"
  die "enrollment exchange failed (HTTP $HTTP_CODE): $(cat "$EXCHANGE_RESP" 2>/dev/null | head -c 200)"
fi

RELAY_ID="$(jq -r '.relay_id // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"
RELAY_SECRET="$(jq -r '.relay_secret // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"
[[ -n "$RELAY_ID" ]] || { install_lifecycle_failed "bad_exchange_response"; die "exchange response missing relay_id"; }
[[ -n "$RELAY_SECRET" ]] || { install_lifecycle_failed "bad_exchange_response"; die "exchange response missing relay_secret"; }

# -----------------------------------------------------------------
# Mesh certificate material. The 0.9.250.89 exchange returns
# cert/key/CA inline (the relay's QUIC listener Fatal-exits
# without a valid cert/key pair on first start — see
# cmd/relay/quic.go — and the renewal loop only runs after a
# successful start, so we cannot rely on self-heal for the FIRST
# cert). If the coordinator omitted the fields (older build),
# fall back to /v1/relay/cert-renew authenticated by the fresh
# relay secret.
# -----------------------------------------------------------------
RELAY_CERT="$(jq -r '.cert // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"
RELAY_KEY="$(jq -r '.key // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"
CA_CERT="$(jq -r '.ca_cert // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"
CA_CERT_PREV="$(jq -r '.ca_cert_prev // empty' "$EXCHANGE_RESP" 2>/dev/null || true)"

if [[ -z "$RELAY_CERT" || -z "$RELAY_KEY" || -z "$CA_CERT" ]]; then
  log "Cert material not in exchange response; falling back to /v1/relay/cert-renew..."
  RENEW_RESP="$(mktemp /tmp/rizoma-relay-renew.XXXXXX)"
  RENEW_CODE="$(curl -sS --max-time 15 \
    -H "Content-Type: application/json" \
    -H "X-Rizoma-Relay-Secret: $RELAY_SECRET" \
    -X POST \
    --data "{\"relay_id\":\"$RELAY_ID\"}" \
    -w '%{http_code}' \
    "${COORDINATOR_URL%/}/v1/relay/cert-renew" \
    -o "$RENEW_RESP" 2>/dev/null)" || RENEW_CODE=000
  if [[ "$RENEW_CODE" != "200" ]]; then
    install_lifecycle_failed "cert_renew_failed"
    die "cert issuance failed (HTTP $RENEW_CODE): $(cat "$RENEW_RESP" 2>/dev/null | head -c 200)"
  fi
  RELAY_CERT="$(jq -r '.cert // empty' "$RENEW_RESP" 2>/dev/null || true)"
  RELAY_KEY="$(jq -r '.key // empty' "$RENEW_RESP" 2>/dev/null || true)"
  CA_CERT="$(jq -r '.ca_cert // empty' "$RENEW_RESP" 2>/dev/null || true)"
  CA_CERT_PREV="$(jq -r '.ca_cert_prev // empty' "$RENEW_RESP" 2>/dev/null || true)"
  rm -f "$RENEW_RESP"
fi
[[ -n "$RELAY_CERT" && -n "$RELAY_KEY" ]] || { install_lifecycle_failed "no_cert_material"; die "no cert material obtained from coordinator"; }

# Write cert material BEFORE the env (the QUIC listener loads it
# on start). CA trust bundle: current CA + prev (rotation grace
# window, 0.9.250.29 semantics — pki dedups by SKI on every
# renewal merge, so a plain concat here is fine).
mkdir -p /etc/rizoma
printf '%s\n' "$CA_CERT" > /etc/rizoma/mesh_ca.pem
if [[ -n "$CA_CERT_PREV" ]]; then
  printf '%s\n' "$CA_CERT_PREV" >> /etc/rizoma/mesh_ca.pem
fi
printf '%s\n' "$RELAY_CERT" > /etc/rizoma/relay_cert.pem
printf '%s\n' "$RELAY_KEY" > /etc/rizoma/relay_key.pem
chmod 600 /etc/rizoma/mesh_ca.pem /etc/rizoma/relay_cert.pem /etc/rizoma/relay_key.pem
chown rizoma-relay:rizoma-relay /etc/rizoma/mesh_ca.pem /etc/rizoma/relay_cert.pem /etc/rizoma/relay_key.pem 2>/dev/null || true

# -----------------------------------------------------------------
# Persist identity + config, start the service
# -----------------------------------------------------------------
mkdir -p /var/lib/rizoma/relay
cat > "$STATE_PATH" <<EOF
{"relay_id":"$RELAY_ID","relay_secret":"$RELAY_SECRET","registered_at":"$(date -u +%Y-%m-%dT%H:%M:%SZ)"}
EOF
chmod 600 "$STATE_PATH"
chown rizoma-relay:rizoma-relay "$STATE_PATH" 2>/dev/null || true

mkdir -p /etc/rizoma
if [[ -f "$ENV_PATH" ]]; then
  cp "$ENV_PATH" "${ENV_PATH}.bak.$(date +%s)"
fi
cat > "$ENV_PATH" <<EOF
# Rizoma relay (enrolled $(date -u +%Y-%m-%dT%H:%M:%SZ) via Add Relay flow)
RIZOMA_RELAY_LISTEN=127.0.0.1:8082
RIZOMA_RELAY_INSECURE_HTTP=true
RIZOMA_RELAY_COORDINATOR_URL=${COORDINATOR_URL}
RIZOMA_RELAY_RELAY_STATE=$STATE_PATH
RIZOMA_RELAY_RELAY_REGION=$REGION
RIZOMA_RELAY_QUIC_LISTEN=0.0.0.0:4243
RIZOMA_RELAY_QUIC_PUBLIC_ADDR=$PUBLIC_ADDR
RIZOMA_RELAY_MAX_CONNECTIONS=$MAX_CONNECTIONS
RIZOMA_RELAY_FIREWALL_MODE=off
RIZOMA_RELAY_MESH_CA_CERT=/etc/rizoma/mesh_ca.pem
RIZOMA_RELAY_MESH_CERT=/etc/rizoma/relay_cert.pem
RIZOMA_RELAY_MESH_KEY=/etc/rizoma/relay_key.pem
EOF
chmod 600 "$ENV_PATH"
chown rizoma-relay:rizoma-relay "$ENV_PATH" 2>/dev/null || true

systemctl daemon-reload
systemctl enable rizoma-relay >/dev/null 2>&1 || true
systemctl restart rizoma-relay

# Give the service a moment to come up before declaring victory
sleep 2
if ! systemctl is-active --quiet rizoma-relay; then
  install_lifecycle_failed "service_failed"
  die "rizoma-relay service did not start — check: journalctl -u rizoma-relay -n 30"
fi

install_lifecycle_complete "$RELAY_ID"
log "Relay enrolled successfully: $RELAY_ID"
echo ""
echo "✓ Relay enrolled: $RELAY_ID"
echo "  Public address: $PUBLIC_ADDR"
echo "  Region:         $REGION"
echo "  Service:        active (rizoma-relay.service)"
echo "  The dashboard's Relays page should now list it."
