#!/usr/bin/env bash
# =============================================================================
#  01-backup-prod.sh
#  À EXÉCUTER SUR LE SERVEUR DE PROD avant tout reset.
#
#  Backup avant de toucher quoi que ce soit :
#   - Dump MySQL complet (compressé)
#   - Snapshot du volume kplan_uploads (uploads utilisateurs)
#   - Snapshot du volume kplan_data (rapports générés)
#   - Export du stack.yaml et .env.stack actuels
#
#  Tout est déposé dans /opt/kplan/backups/<timestamp>/
#  → tu peux restaurer n'importe quoi à partir de ce dossier.
# =============================================================================

set -euo pipefail

STACK_NAME=kplan
BACKUP_ROOT=/opt/kplan/backups
TS=$(date +%Y%m%d-%H%M%S)
BACKUP_DIR="${BACKUP_ROOT}/${TS}"

# Couleurs
if [ -t 1 ]; then
    C_BLUE='\033[1;34m'; C_GREEN='\033[1;32m'; C_YELLOW='\033[1;33m'
    C_RED='\033[1;31m';  C_RESET='\033[0m'
else
    C_BLUE=''; C_GREEN=''; C_YELLOW=''; C_RED=''; C_RESET=''
fi
log()  { printf "${C_BLUE}▸ %s${C_RESET}\n" "$*"; }
ok()   { printf "${C_GREEN}✓ %s${C_RESET}\n" "$*"; }
warn() { printf "${C_YELLOW}⚠ %s${C_RESET}\n" "$*"; }
err()  { printf "${C_RED}✗ %s${C_RESET}\n" "$*" >&2; }

# Sanity
[ "$(id -u)" -eq 0 ] || { err "Lance ce script en root (ou via sudo)"; exit 1; }

mkdir -p "$BACKUP_DIR"
log "Backup dans : $BACKUP_DIR"

# -----------------------------------------------------------------------------
# 1) Charger les credentials MySQL depuis .env.stack
# -----------------------------------------------------------------------------
ENV_FILE="${ENV_FILE:-/opt/kplan/.env.stack}"
[ -f "$ENV_FILE" ] || { err "$ENV_FILE introuvable — précise ENV_FILE=/path/.env.stack"; exit 1; }

log "Lecture des credentials MySQL depuis $ENV_FILE"
set -a; . "$ENV_FILE"; set +a

# -----------------------------------------------------------------------------
# 2) Dump MySQL complet
# -----------------------------------------------------------------------------
log "Dump MySQL ${DB_NAME}@${DB_HOST}..."
DUMP_FILE="${BACKUP_DIR}/mysql-${DB_NAME}.sql.gz"

# On utilise un container mysql pour ne pas dépendre du client local
docker run --rm \
    -e MYSQL_PWD="${DB_PASSWORD}" \
    mysql:8.0 \
    mysqldump \
        --host="${DB_HOST}" \
        --port="${DB_PORT:-3306}" \
        --user="${DB_USER}" \
        --single-transaction \
        --routines \
        --triggers \
        --events \
        --no-tablespaces \
        "${DB_NAME}" \
    | gzip > "$DUMP_FILE"

DUMP_SIZE=$(du -h "$DUMP_FILE" | cut -f1)
ok "MySQL dumpé : $DUMP_FILE ($DUMP_SIZE)"

# -----------------------------------------------------------------------------
# 3) Snapshot des volumes critiques (uploads + data)
# -----------------------------------------------------------------------------
backup_volume() {
    local vol="$1"
    local out="${BACKUP_DIR}/${vol}.tar.gz"

    if ! docker volume inspect "$vol" >/dev/null 2>&1; then
        warn "Volume $vol absent, skip"
        return
    fi

    log "Backup du volume $vol..."
    docker run --rm \
        -v "${vol}:/source:ro" \
        -v "${BACKUP_DIR}:/backup" \
        alpine \
        sh -c "cd /source && tar -czf /backup/${vol}.tar.gz ."

    SIZE=$(du -h "$out" | cut -f1)
    ok "$vol → $out ($SIZE)"
}

# Essaie les deux conventions de nommage
for v in kplan_uploads kplan_data; do
    if docker volume inspect "$v" >/dev/null 2>&1; then
        backup_volume "$v"
    elif docker volume inspect "${STACK_NAME}_${v#kplan_}" >/dev/null 2>&1; then
        backup_volume "${STACK_NAME}_${v#kplan_}"
    else
        warn "Volume $v / ${STACK_NAME}_${v#kplan_} introuvable"
    fi
done

# -----------------------------------------------------------------------------
# 4) Sauvegarder la config actuelle
# -----------------------------------------------------------------------------
log "Sauvegarde de la config..."
[ -f /opt/kplan/stack.yaml ]   && cp /opt/kplan/stack.yaml   "${BACKUP_DIR}/stack.yaml.bak"
[ -f /opt/kplan/.env.stack ]   && cp /opt/kplan/.env.stack   "${BACKUP_DIR}/.env.stack.bak"
[ -f /opt/kplan/deploy.sh ]    && cp /opt/kplan/deploy.sh    "${BACKUP_DIR}/deploy.sh.bak"

# Snapshot des services Swarm actuels
docker stack services "$STACK_NAME" > "${BACKUP_DIR}/swarm-services-snapshot.txt" 2>&1 || true
docker service ls > "${BACKUP_DIR}/all-services.txt" 2>&1 || true
docker volume ls > "${BACKUP_DIR}/all-volumes.txt" 2>&1 || true

ok "Config sauvegardée"

# -----------------------------------------------------------------------------
# 5) Récap final
# -----------------------------------------------------------------------------
echo
ok "Backup complet terminé : $BACKUP_DIR"
echo
echo "Contenu :"
ls -lh "$BACKUP_DIR" | sed 's/^/    /'
echo
echo "Total : $(du -sh "$BACKUP_DIR" | cut -f1)"
echo
echo "→ Tu peux maintenant lancer 02-build-and-push.sh sur ton poste de dev,"
echo "  puis 03-redeploy.sh ici sur le serveur."
