#!/bin/bash
# ============================================================================
# ODETOOL — Sauvegarde locale quotidienne (bases MySQL + dossier saves/)
# ============================================================================
# Sauvegarde, dans un dossier horodaté :
#   - la base centrale odetool_clipboard (comptes, sessions, tags…)
#   - toutes les bases workspace_* (une par espace de travail)
#   - le dossier saves/ (exports locaux)
# Un sous-dossier par exécution : <BACKUP_DIR>/<AAAA-MM-JJ_HHMMSS>/
# Rétention : les dossiers plus vieux que RETENTION_DAYS sont supprimés.
#
# Identifiants MySQL : lus dans api/Config/db_credentials.php (source unique).
# Emploi manuel :   ./sauvegarde-odetool.sh [dossier_destination]
# Emploi automatique : cron (voir docs/SAUVEGARDE-LOCALE.md)
# ============================================================================
set -uo pipefail

# ── Réglages ────────────────────────────────────────────────────────────────
# Destination par défaut : iCloud Drive (protection contre la panne du disque
# du Mac — les fichiers y sont conservés localement ET synchronisés dans le
# cloud). Pour un dossier local simple : passer le chemin en argument.
BACKUP_DIR="${1:-$HOME/Library/Mobile Documents/com~apple~CloudDocs/ODETOOL-sauvegardes}"
RETENTION_DAYS=30
ODETOOL_ROOT="/Applications/MAMP/htdocs/odetool"
MYSQL_BIN="/Applications/MAMP/Library/bin/mysql80/bin"
PHP_BIN="/Applications/MAMP/bin/php/php8.3.30/bin/php"
SOCKET="/Applications/MAMP/tmp/mysql/mysql.sock"

DATE=$(date +%Y-%m-%d_%H%M%S)
DEST="$BACKUP_DIR/$DATE"
LOG="$BACKUP_DIR/sauvegarde.log"

# ── Identifiants (depuis db_credentials.php) ────────────────────────────────
CRED_FILE="$ODETOOL_ROOT/api/Config/db_credentials.php"
if [ ! -f "$CRED_FILE" ]; then
  echo "ERREUR : $CRED_FILE introuvable" | tee -a "$LOG" >&2; exit 1
fi
eval "$($PHP_BIN -r '
$c = require $argv[1];
echo "DB_USER=" . escapeshellarg($c["user"]) . " DB_PASS=" . escapeshellarg($c["password"]);
' "$CRED_FILE" 2>/dev/null)" || { echo "ERREUR : lecture db_credentials.php" | tee -a "$LOG" >&2; exit 1; }

# ── Préparation ─────────────────────────────────────────────────────────────
mkdir -p "$DEST"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Sauvegarde ODETOOL → $DEST" | tee -a "$LOG"

MYSQL="$MYSQL_BIN/mysql --socket=$SOCKET -u$DB_USER"
# --single-transaction : sauvegarde cohérente sans verrouiller les tables
# InnoDB (important : la sauvegarde de midi se fait pendant l'usage de l'app)
DUMP="$MYSQL_BIN/mysqldump --single-transaction --quick --socket=$SOCKET -u$DB_USER"
[ -n "$DB_PASS" ] && MYSQL="$MYSQL -p$DB_PASS" && DUMP="$DUMP -p$DB_PASS"

ERRORS=0

# ── 1. Bases de données ─────────────────────────────────────────────────────
DATABASES=$($MYSQL -N -e "SHOW DATABASES" 2>>"$LOG" \
  | grep -E '^(odetool_clipboard|workspace_.+)$' | sort)

if [ -z "$DATABASES" ]; then
  echo "  ERREUR : aucune base trouvée (MySQL est-il démarré ?)" | tee -a "$LOG" >&2
  exit 1
fi

for DB in $DATABASES; do
  if $DUMP --databases "$DB" 2>>"$LOG" | gzip > "$DEST/$DB.sql.gz"; then
    SIZE=$(du -h "$DEST/$DB.sql.gz" | cut -f1)
    echo "  OK  $DB ($SIZE)" | tee -a "$LOG"
  else
    echo "  ECHEC $DB" | tee -a "$LOG" >&2; ERRORS=$((ERRORS+1))
  fi
done

# ── 2. Dossier saves/ ───────────────────────────────────────────────────────
if [ -d "$ODETOOL_ROOT/saves" ]; then
  if tar -czf "$DEST/saves.tar.gz" -C "$ODETOOL_ROOT" saves 2>>"$LOG"; then
    echo "  OK  saves/ ($(du -h "$DEST/saves.tar.gz" | cut -f1))" | tee -a "$LOG"
  else
    echo "  ECHEC saves/" | tee -a "$LOG" >&2; ERRORS=$((ERRORS+1))
  fi
fi

# ── 3. Manifeste (liste du contenu, pour s'y retrouver) ────────────────────
{
  echo "Sauvegarde ODETOOL du $(date '+%Y-%m-%d %H:%M:%S')"
  echo "Bases :"
  for DB in $DATABASES; do echo "  - $DB"; done
  echo "Fichiers :"
  ls -1 "$DEST" | sed 's/^/  - /'
  echo "Restauration : zcat <fichier>.sql.gz | mysql --socket=$SOCKET -u<user> -p"
} > "$DEST/MANIFEST.txt"

# ── 4. Rétention ───────────────────────────────────────────────────────────
if [ "$RETENTION_DAYS" -gt 0 ]; then
  find "$BACKUP_DIR" -maxdepth 1 -type d -name "20*_*" -mtime +$RETENTION_DAYS -exec rm -rf {} \; 2>/dev/null
  echo "  Rétention : dossiers de plus de $RETENTION_DAYS jours supprimés" | tee -a "$LOG"
fi

if [ "$ERRORS" -gt 0 ]; then
  echo "[$(date '+%Y-%m-%d %H:%M:%S')] TERMINÉ AVEC $ERRORS ERREUR(S)" | tee -a "$LOG" >&2
  exit 1
fi
echo "[$(date '+%Y-%m-%d %H:%M:%S')] Terminé sans erreur" | tee -a "$LOG"
exit 0
