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

usage() {
  cat <<'USAGE'
Usage:
  hermes-emergency-bundle-create.sh [output-dir]

Creates a GPG-encrypted emergency bundle containing sensitive recovery files
that are intentionally excluded from the normal GitHub Hermes backups.

Default output-dir:
  /root/hermes-emergency-bundles

Passphrase:
  Interactive GPG prompt by default.
  Or set BUNDLE_PASSPHRASE_FILE=/root/path/to/passphrase-file for unattended use.

Safety:
  - Does not print secret values.
  - Uses an allow-list of sensitive recovery files.
  - Does not include logs, caches, locks, PIDs, or sandboxes.
USAGE
}

if [ "${1:-}" = "-h" ] || [ "${1:-}" = "--help" ]; then
  usage
  exit 0
fi

OUT_DIR="${1:-/root/hermes-emergency-bundles}"
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
HOST="$(hostname -s 2>/dev/null || hostname)"
WORK_DIR="$(mktemp -d)"
PAYLOAD_DIR="$WORK_DIR/payload"
ARCHIVE="$WORK_DIR/hermes-emergency-bundle-${HOST}-${STAMP}.tar.zst"
OUT_FILE="$OUT_DIR/hermes-emergency-bundle-${HOST}-${STAMP}.tar.zst.gpg"

cleanup() {
  rm -rf "$WORK_DIR"
}
trap cleanup EXIT

install -d -m 700 "$OUT_DIR"
install -d -m 700 "$PAYLOAD_DIR"

copy_if_exists() {
  src="$1"
  dest="$PAYLOAD_DIR/${src#/}"
  if [ -e "$src" ]; then
    install -d -m 700 "$(dirname "$dest")"
    cp -a "$src" "$dest"
    printf '%s\n' "${src#/}" >> "$PAYLOAD_DIR/MANIFEST.paths"
  fi
}

# Root Hermes sensitive state.
copy_if_exists /root/.hermes/.env
copy_if_exists /root/.hermes/auth.json
copy_if_exists /root/.hermes/state.db
copy_if_exists /root/.hermes/state.db-shm
copy_if_exists /root/.hermes/state.db-wal

# Uma Hermes sensitive state.
copy_if_exists /home/uma/.hermes/.env
copy_if_exists /home/uma/.hermes/auth.json
copy_if_exists /home/uma/.hermes/state.db
copy_if_exists /home/uma/.hermes/state.db-shm
copy_if_exists /home/uma/.hermes/state.db-wal

# Git and local registry credentials used for recovery operations.
copy_if_exists /root/.git-credentials
copy_if_exists /root/.gitea_admin_password
copy_if_exists /root/.gitea_npm_token
copy_if_exists /root/.gitea_npm_token_home

# Tailscale machine state is sensitive. Restoring it is optional; a fresh
# `tailscale up` login is often cleaner, but this preserves a break-glass copy.
copy_if_exists /var/lib/tailscale/tailscaled.state

if [ ! -s "$PAYLOAD_DIR/MANIFEST.paths" ]; then
  echo "No emergency files found to bundle." >&2
  exit 1
fi

cat > "$PAYLOAD_DIR/README.txt" <<README
Hermes emergency bundle for ${HOST}
Created UTC: ${STAMP}

This encrypted bundle contains sensitive files excluded from normal GitHub
backups, such as .env files, provider auth state, Git credentials, local Gitea
tokens, optional Tailscale state, and Hermes state.db files.

Decrypt only into a staging directory first. Inspect paths before copying
anything into a live VM.
README

tar -C "$PAYLOAD_DIR" -I zstd -cf "$ARCHIVE" .

gpg_args=(--symmetric --cipher-algo AES256 --output "$OUT_FILE")
if [ -n "${BUNDLE_PASSPHRASE_FILE:-}" ]; then
  gpg_args=(--batch --yes --pinentry-mode loopback --passphrase-file "$BUNDLE_PASSPHRASE_FILE" "${gpg_args[@]}")
fi

gpg "${gpg_args[@]}" "$ARCHIVE"
chmod 600 "$OUT_FILE"

echo "Encrypted emergency bundle created: $OUT_FILE"
echo "Included path list is encrypted inside the bundle; no secret values printed."
