#!/usr/bin/env bash
# Encrypted backup of database, uploads and vault documents, with rotation and optional off-site copy.
# Config (environment or /etc/cioclub/backup.env): APP_DIR, BACKUP_DIR, DB_NAME, MYSQL_CNF, KEY_FILE, KEEP_DAILY, KEEP_WEEKLY, BACKUP_S3_URI
set -euo pipefail
# shellcheck source=/dev/null
[ -f /etc/cioclub/backup.env ] && . /etc/cioclub/backup.env
APP_DIR="${APP_DIR:-/var/www/cioclub}"
BACKUP_DIR="${BACKUP_DIR:-/var/backups/cioclub}"
DB_NAME="${DB_NAME:-cioclub}"
MYSQL_CNF="${MYSQL_CNF:-/etc/cioclub/backup.cnf}"
KEY_FILE="${KEY_FILE:-/etc/cioclub/backup.key}"
KEEP_DAILY="${KEEP_DAILY:-14}"
KEEP_WEEKLY="${KEEP_WEEKLY:-8}"
SHARED="$APP_DIR/shared"

for f in "$MYSQL_CNF" "$KEY_FILE"; do [ -r "$f" ] || { echo "Missing or unreadable: $f" >&2; exit 1; }; done
umask 077
STAMP="$(date -u +%Y%m%dT%H%M%SZ)"
WORK="$(mktemp -d)"
trap 'rm -rf "$WORK"' EXIT
mkdir -p "$BACKUP_DIR/daily" "$BACKUP_DIR/weekly"

mysqldump --defaults-extra-file="$MYSQL_CNF" --single-transaction --quick --routines --triggers --hex-blob \
  --default-character-set=utf8mb4 "$DB_NAME" > "$WORK/db.sql"
tar -C "$SHARED" -cf "$WORK/files.tar" --ignore-failed-read public/uploads storage/vault 2>/dev/null || tar -C "$SHARED" -cf "$WORK/files.tar" --files-from /dev/null
( cd "$WORK" && sha256sum db.sql files.tar > SHA256SUMS )
tar -C "$WORK" -czf "$WORK/bundle.tgz" db.sql files.tar SHA256SUMS
OUT="$BACKUP_DIR/daily/cioclub-$STAMP.tgz.enc"
openssl enc -aes-256-cbc -pbkdf2 -iter 200000 -salt -pass "file:$KEY_FILE" -in "$WORK/bundle.tgz" -out "$OUT"
sha256sum "$OUT" > "$OUT.sha256"

if [ "$(date -u +%u)" = "7" ]; then cp "$OUT" "$OUT.sha256" "$BACKUP_DIR/weekly/"; fi
ls -1t "$BACKUP_DIR"/daily/*.enc 2>/dev/null | tail -n +"$((KEEP_DAILY + 1))" | while read -r old; do rm -f "$old" "$old.sha256"; done
ls -1t "$BACKUP_DIR"/weekly/*.enc 2>/dev/null | tail -n +"$((KEEP_WEEKLY + 1))" | while read -r old; do rm -f "$old" "$old.sha256"; done

if [ -n "${BACKUP_S3_URI:-}" ] && command -v aws >/dev/null 2>&1; then
  aws s3 cp "$OUT" "$BACKUP_S3_URI/" --only-show-errors && aws s3 cp "$OUT.sha256" "$BACKUP_S3_URI/" --only-show-errors
fi
echo "$(date -u +%FT%TZ) backup ok $OUT ($(du -h "$OUT" | cut -f1))"
