#!/usr/bin/env bash
#
# Backup automatique de la BDD VITRINE.
# Usage : ./backup.sh
#
# Crontab : 0 2 * * * /chemin/vers/www/scripts/backup.sh >> /var/log/vitrine-backup.log 2>&1

set -euo pipefail

# --- Chemins ---
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
BACKUP_DIR="${SCRIPT_DIR}/../storage/backups"
ENV_FILE="${PROJECT_ROOT}/.env"

# --- Rétention ---
RETENTION_DAYS=30

# --- Chargement du .env ---
if [ ! -f "${ENV_FILE}" ]; then
    echo "[ERROR] .env introuvable : ${ENV_FILE}" >&2
    exit 1
fi

# Export des variables du .env (ignore les commentaires et lignes vides)
set -a
# shellcheck disable=SC1090
source <(grep -v '^\s*#' "${ENV_FILE}" | grep -v '^\s*$' | sed 's/\r$//')
set +a

# --- Vérifications ---
: "${DB_HOST:?DB_HOST manquant dans .env}"
: "${DB_PORT:?DB_PORT manquant dans .env}"
: "${DB_NAME_APP:?DB_NAME_APP manquant dans .env}"
: "${DB_USER:?DB_USER manquant dans .env}"

# --- Recherche de mysqldump ---
# 1. Variable MYSQL_BIN_DIR du .env si définie
# 2. Commande mysqldump dans le PATH
# 3. Chemins WAMP courants
MYSQLDUMP=""
if [ -n "${MYSQL_BIN_DIR:-}" ] && [ -x "${MYSQL_BIN_DIR}/mysqldump.exe" ]; then
    MYSQLDUMP="${MYSQL_BIN_DIR}/mysqldump.exe"
elif command -v mysqldump >/dev/null 2>&1; then
    MYSQLDUMP="mysqldump"
else
    for candidate in /c/wamp64/bin/mysql/mysql*/bin/mysqldump.exe \
                     /c/xampp/mysql/bin/mysqldump.exe \
                     /usr/bin/mysqldump; do
        if [ -x "${candidate}" ]; then
            MYSQLDUMP="${candidate}"
            break
        fi
    done
fi

if [ -z "${MYSQLDUMP}" ]; then
    echo "[ERROR] mysqldump introuvable. Définissez MYSQL_BIN_DIR dans .env." >&2
    exit 1
fi

# --- Préparation ---
mkdir -p "${BACKUP_DIR}"

TIMESTAMP=$(date +%Y%m%d_%H%M%S)
BACKUP_FILE="${BACKUP_DIR}/${DB_NAME_APP}_${TIMESTAMP}.sql.gz"

echo "[$(date '+%Y-%m-%d %H:%M:%S')] → Backup de ${DB_NAME_APP} vers ${BACKUP_FILE}"

# --- Dump + compression ---
"${MYSQLDUMP}" \
    --host="${DB_HOST}" \
    --port="${DB_PORT}" \
    --user="${DB_USER}" \
    ${DB_PASSWORD:+--password="${DB_PASSWORD}"} \
    --single-transaction \
    --routines \
    --triggers \
    --events \
    --default-character-set=utf8mb4 \
    --no-tablespaces \
    "${DB_NAME_APP}" \
    | gzip -9 > "${BACKUP_FILE}"

# --- Vérification intégrité ---
if [ ! -s "${BACKUP_FILE}" ]; then
    echo "[ERROR] Le fichier de backup est vide : ${BACKUP_FILE}" >&2
    rm -f "${BACKUP_FILE}"
    exit 1
fi

if ! gzip -t "${BACKUP_FILE}" 2>/dev/null; then
    echo "[ERROR] Le fichier gzip est corrompu : ${BACKUP_FILE}" >&2
    rm -f "${BACKUP_FILE}"
    exit 1
fi

SIZE=$(du -h "${BACKUP_FILE}" | cut -f1)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✓ Backup créé (${SIZE})"

# --- Purge des backups anciens ---
echo "[$(date '+%Y-%m-%d %H:%M:%S')] → Purge des backups de plus de ${RETENTION_DAYS} jours"

PURGED=0
while IFS= read -r -d '' old_file; do
    echo "   × suppression : $(basename "${old_file}")"
    rm -f "${old_file}"
    PURGED=$((PURGED + 1))
done < <(find "${BACKUP_DIR}" -name "${DB_NAME_APP}_*.sql.gz" -type f -mtime +${RETENTION_DAYS} -print0)

echo "[$(date '+%Y-%m-%d %H:%M:%S')] ✓ ${PURGED} backup(s) purgé(s)"

# --- Récapitulatif ---
TOTAL_BACKUPS=$(find "${BACKUP_DIR}" -name "${DB_NAME_APP}_*.sql.gz" -type f | wc -l)
TOTAL_SIZE=$(du -sh "${BACKUP_DIR}" 2>/dev/null | cut -f1)
echo "[$(date '+%Y-%m-%d %H:%M:%S')] ℹ ${TOTAL_BACKUPS} backup(s) au total (${TOTAL_SIZE})"
