#!/usr/bin/env bash
# wp-backup.sh, nightly off-server WordPress backup via mysqldump + restic.
# Install at /usr/local/sbin/wp-backup.sh, run from root crontab.
# Source: https://techearl.com/wordpress-offsite-backups-3-2-1-with-verification
# Site:   https://techearl.com/
set -euo pipefail

SITE="example.com"
WP_DIR="/var/www/${SITE}"
DB_NAME="wp_production"
DUMP_DIR="/var/lib/backup/dumps"
LOG="/var/log/wp-backup.log"

# restic destination + key
export RESTIC_REPOSITORY="s3:s3.us-east-1.amazonaws.com/example-backups/${SITE}"
export RESTIC_PASSWORD_FILE="/root/.restic.password"
export AWS_ACCESS_KEY_ID=$(cat /root/.restic.aws-key)
export AWS_SECRET_ACCESS_KEY=$(cat /root/.restic.aws-secret)

ts=$(date -u +'%Y-%m-%dT%H-%M-%SZ')

log() { echo "[$(date -u +'%Y-%m-%dT%H:%M:%SZ')] $*" | tee -a "$LOG"; }

# 1) Database dump (atomic, single-transaction for InnoDB)
mkdir -p "$DUMP_DIR"
chown backup:backup "$DUMP_DIR"
chmod 700 "$DUMP_DIR"
DUMP_FILE="${DUMP_DIR}/${DB_NAME}-${ts}.sql.gz"
log "dumping ${DB_NAME} to ${DUMP_FILE}"
mysqldump \
  --defaults-extra-file=/root/.my-backup.cnf \
  --single-transaction \
  --quick \
  --routines \
  --triggers \
  --events \
  --set-gtid-purged=OFF \
  --no-tablespaces \
  "$DB_NAME" \
  | gzip > "$DUMP_FILE"

# 2) restic backup of WordPress files + the fresh dump, run as backup user
log "restic backup starting"
sudo -u backup --preserve-env=RESTIC_REPOSITORY,RESTIC_PASSWORD_FILE,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY \
  restic backup \
    --tag "nightly" \
    --tag "${SITE}" \
    --host "${SITE}" \
    --exclude "${WP_DIR}/wp-content/cache" \
    --exclude "${WP_DIR}/wp-content/uploads/cache" \
    --exclude "*.log" \
    --exclude "*.tmp" \
    "$WP_DIR" \
    "$DUMP_DIR"

# 3) Prune policy (keep N daily, weekly, monthly, yearly)
log "restic forget + prune"
sudo -u backup --preserve-env=RESTIC_REPOSITORY,RESTIC_PASSWORD_FILE,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY \
  restic forget \
    --tag "nightly" \
    --host "${SITE}" \
    --keep-daily 14 \
    --keep-weekly 8 \
    --keep-monthly 12 \
    --keep-yearly 5 \
    --prune

# 4) Sanity-check by listing the latest snapshot
log "latest snapshots:"
sudo -u backup --preserve-env=RESTIC_REPOSITORY,RESTIC_PASSWORD_FILE,AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY \
  restic snapshots --tag "nightly" --last | tee -a "$LOG"

# 5) Clean up local dump (already in restic)
find "$DUMP_DIR" -name '*.sql.gz' -mtime +1 -delete

log "backup complete"
