#!/usr/bin/env bash
#
# Dump the Postgres database to a timestamped pg_dump custom-format file
# and rotate to the most recent N backups.
#
# Usage:
#   ./scripts/backup-db.sh                              # default: ./backups, keep 7
#   BACKUP_DIR=/var/backups RETENTION=14 ./scripts/backup-db.sh
#
# Environment overrides:
#   BACKUP_DIR   target directory (default: ./backups)
#   RETENTION    number of backups to keep (default: 7)
#   CONTAINER    postgres container name (default: recall-postgres)
#   DB_USER      postgres user (default: recall)
#   DB_NAME      database name (default: recall)
#
# Restore (verify regularly!):
#   docker exec -i <pg_container> pg_restore -U <user> -d <db> --clean --if-exists < backup-XXXX.dump
#
# An untested backup is no backup. Restore to a scratch DB at least monthly.

set -euo pipefail

BACKUP_DIR="${BACKUP_DIR:-./backups}"
RETENTION="${RETENTION:-7}"
CONTAINER="${CONTAINER:-pac-postgres}"
DB_USER="${DB_USER:-pac}"
DB_NAME="${DB_NAME:-pac}"

if ! docker inspect "$CONTAINER" >/dev/null 2>&1; then
  echo "ERROR: container '$CONTAINER' not found. Is the postgres service running?" >&2
  exit 1
fi

mkdir -p "$BACKUP_DIR"
TS="$(date +%Y%m%d-%H%M%S)"
OUT="$BACKUP_DIR/pac-$TS.dump"

echo "==> dumping $DB_NAME from $CONTAINER → $OUT"
docker exec "$CONTAINER" pg_dump -U "$DB_USER" -F c "$DB_NAME" > "$OUT"
SIZE=$(du -h "$OUT" | awk '{print $1}')
echo "==> wrote $SIZE"

# Rotate: keep most recent $RETENTION dumps, delete the rest.
OLD_FILES=$(ls -1t "$BACKUP_DIR"/pac-*.dump 2>/dev/null | tail -n +$((RETENTION + 1)) || true)
if [[ -n "$OLD_FILES" ]]; then
  COUNT=$(printf '%s\n' "$OLD_FILES" | wc -l | tr -d ' ')
  echo "==> rotating: removing $COUNT old backup(s)"
  printf '%s\n' "$OLD_FILES" | sed 's/^/    /'
  printf '%s\n' "$OLD_FILES" | xargs rm -f
fi

echo "==> recent backups:"
ls -lh "$BACKUP_DIR"/pac-*.dump 2>/dev/null | tail -n "$RETENTION"
