#!/usr/bin/env bash
#
# EXAMPLE / REFERENCE ONLY — not installed by the etminan package. Place it on
# the verifier host and point the Job's ClientRunBeforeJob at it (see the
# example path in etminan-jobs.conf).
#
# etminan-verifier-snapshot.sh — WAL-safe snapshot of the verifier trust store,
# run as a Bacula ClientRunBeforeJob so the FileSet backs up a consistent copy
# rather than the live SQLite files. Mirrors the FDS fds.db.snapshot pattern.
#
# Why a snapshot and not a raw file copy:
#   - baseline.db is SQLite in WAL mode. A naive cp of baseline.db while the
#     verifier is mid-write (or without its -wal/-shm sidecars) yields a stale
#     or corrupt restore. `sqlite3 .backup` produces an atomic, consistent
#     point-in-time copy with no sidecars needed.
#   - baseline.db.audit-head is an EXTERNAL anchor holding the highest committed
#     (seq, entry_hash) of the hash-chained audit_log. verify_chain FAILS (and
#     reports it as tampering) if the DB is BEHIND its anchor. If we copied the
#     live DB and the live anchor at two different instants, the anchor could be
#     ahead of the DB snapshot -> restore looks tampered. We therefore DERIVE the
#     anchor from the snapshot itself, so the snapshot DB and its anchor are the
#     same generation by construction — zero race window.
set -euo pipefail

DB="${ETMINAN_BASELINE_DB:-/var/lib/etminan-verifier/baseline.db}"
SNAP_DIR="${ETMINAN_BACKUP_DIR:-/var/backups/etminan}"

install -d -m 0700 "$SNAP_DIR"

if [ ! -f "$DB" ]; then
  echo "etminan snapshot: no baseline.db at $DB — nothing to snapshot" >&2
  exit 0
fi

SNAP="$SNAP_DIR/baseline.db.snapshot"

# 1) Consistent point-in-time copy of the whole DB (commits the WAL internally).
sqlite3 "$DB" ".backup '$SNAP'"

# 2) Derive the audit anchor FROM the snapshot, so DB and anchor match exactly.
#    (Restore places this as <db>.audit-head next to the restored baseline.db.)
head_row="$(sqlite3 "$SNAP" \
  "SELECT seq || ' ' || entry_hash FROM audit_log ORDER BY seq DESC LIMIT 1;")"
if [ -n "$head_row" ]; then
  printf '%s\n' "$head_row" > "$SNAP.audit-head"
else
  # empty audit_log (fresh verifier): no anchor yet, mirror that on restore.
  rm -f "$SNAP.audit-head"
fi

chmod 0600 "$SNAP" "$SNAP.audit-head" 2>/dev/null || true
echo "etminan snapshot: wrote $SNAP (+ .audit-head) from $DB"
