#!/bin/sh
set -eu
umask 077

: "${HAYVA_BACKUP_DIR:?Set HAYVA_BACKUP_DIR to an absolute off-host backup staging path}"
: "${AGE_RECIPIENT:?Set AGE_RECIPIENT to the separately controlled backup public key}"

case "$HAYVA_BACKUP_DIR" in
  /*) ;;
  *) echo "HAYVA_BACKUP_DIR must be absolute" >&2; exit 2 ;;
esac
if [ "$HAYVA_BACKUP_DIR" = "/" ]; then
  echo "HAYVA_BACKUP_DIR cannot be the filesystem root" >&2
  exit 2
fi

project="${HAYVA_COMPOSE_PROJECT:-hayva}"
case "$project" in
  *[!A-Za-z0-9_-]*|'') echo "HAYVA_COMPOSE_PROJECT is invalid" >&2; exit 2 ;;
esac
compose_file="${HAYVA_COMPOSE_FILE:-docker-compose.yml}"
env_file="${HAYVA_ENV_FILE:-.env}"
command -v docker >/dev/null
command -v age >/dev/null
command -v sha256sum >/dev/null
mkdir -p "$HAYVA_BACKUP_DIR"
temporary="$(mktemp -d "${TMPDIR:-/tmp}/hayva-backup.XXXXXX")"
case "$temporary" in /tmp/hayva-backup.*|*/hayva-backup.*) ;; *) exit 2 ;; esac
trap 'rm -rf -- "$temporary"' EXIT HUP INT TERM

timestamp="$(date -u +%Y%m%dT%H%M%SZ)"
archive="$HAYVA_BACKUP_DIR/hayva-$timestamp.tar.gz.age"

docker compose --project-name "$project" --env-file "$env_file" \
  -f "$compose_file" exec -T postgres sh -c \
  'exec pg_dump --username "$POSTGRES_USER" --dbname "$POSTGRES_DB" --format=custom' \
  > "$temporary/database.dump"

docker run --rm --network none \
  -v "${project}_browser-profiles:/source:ro" -v "$temporary:/backup" \
  alpine:3.23 tar -C /source -czf /backup/browser-profiles.tar.gz .
docker run --rm --network none \
  -v "${project}_computer-artifacts:/source:ro" -v "$temporary:/backup" \
  alpine:3.23 tar -C /source -czf /backup/computer-artifacts.tar.gz .

cat > "$temporary/manifest.txt" <<EOF
schema=hayva-backup-v1
created_at=$timestamp
compose_project=$project
contents=database.dump,browser-profiles.tar.gz,computer-artifacts.tar.gz
EOF

tar -C "$temporary" -czf "$temporary/payload.tar.gz" \
  database.dump browser-profiles.tar.gz computer-artifacts.tar.gz manifest.txt
age --recipient "$AGE_RECIPIENT" --output "$archive" "$temporary/payload.tar.gz"
sha256sum "$archive" > "$archive.sha256"
printf 'Encrypted backup created: %s\n' "$archive"
printf 'Transfer the .age and .sha256 files to immutable off-host storage.\n'
