#!/usr/bin/env bash
# Rolling DB backups: gzip dump into storage/app/database-backups, delete older than RETENTION_DAYS.
# Reads Laravel .env from project root. Cron example (daily 2:15):
#   15 2 * * * BACKUP_DIR=/path/to/backups /path/to/lexlegio/scripts/backup-database.sh >> /var/log/db-backup.log 2>&1
#
# Optional env overrides:
#   BACKUP_DIR      (default: <project>/storage/app/database-backups)
#   RETENTION_DAYS  (default: 3)
#   MYSQLDUMP       (default: mysqldump) — e.g. /Applications/MAMP/Library/bin/mysqldump

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
ENV_FILE="$PROJECT_ROOT/.env"

BACKUP_DIR="${BACKUP_DIR:-$PROJECT_ROOT/storage/app/database-backups}"
RETENTION_DAYS="${RETENTION_DAYS:-3}"
MYSQLDUMP_BIN="${MYSQLDUMP:-mysqldump}"

if [[ ! -f "$ENV_FILE" ]]; then
  echo "error: missing $ENV_FILE" >&2
  exit 1
fi

# shellcheck disable=SC1090
set -a
# shellcheck source=/dev/null
. "$ENV_FILE"
set +a

mkdir -p "$BACKUP_DIR"
ts="$(date +%Y-%m-%d_%H%M%S)"
conn="${DB_CONNECTION:-mysql}"

backup_mysql_family() {
  local out="$1"
  if ! command -v "$MYSQLDUMP_BIN" >/dev/null 2>&1; then
    echo "error: mysqldump not found ($MYSQLDUMP_BIN). Set MYSQLDUMP in the environment." >&2
    exit 1
  fi
  local -a args=(
    "$MYSQLDUMP_BIN"
    --single-transaction
    --quick
    --lock-tables=false
    --no-tablespaces
  )
  if [[ -n "${DB_SOCKET:-}" ]]; then
    args+=(--socket="$DB_SOCKET")
  else
    args+=(-h"${DB_HOST:-127.0.0.1}" -P"${DB_PORT:-3306}")
  fi
  args+=(-u"${DB_USERNAME:-root}" -p"${DB_PASSWORD:-}")
  args+=("${DB_DATABASE:?DB_DATABASE is not set}")
  "${args[@]}" | gzip -c >"$out"
}

backup_sqlite() {
  local out="$1"
  local dbpath="${DB_DATABASE:?DB_DATABASE is not set}"
  if [[ "$dbpath" != /* ]]; then
    dbpath="$PROJECT_ROOT/$dbpath"
  fi
  if [[ ! -f "$dbpath" ]]; then
    echo "error: SQLite file not found: $dbpath" >&2
    exit 1
  fi
  gzip -c "$dbpath" >"$out"
}

case "$conn" in
  mysql | mariadb)
    f="$BACKUP_DIR/db-backup-${conn}-${ts}.sql.gz"
    backup_mysql_family "$f"
    ;;
  sqlite)
    f="$BACKUP_DIR/db-backup-sqlite-${ts}.sql.gz"
    backup_sqlite "$f"
    ;;
  *)
    echo "error: unsupported DB_CONNECTION=$conn (use mysql, mariadb, or sqlite)" >&2
    exit 1
    ;;
esac

echo "backup: $f"

# Drop backups older than RETENTION_DAYS (mtime).
find "$BACKUP_DIR" -maxdepth 1 -type f -name 'db-backup-*.sql.gz' -mtime "+${RETENTION_DAYS}" -print -delete
