#!/bin/bash

# =============================================================
# BACKUP SCRIPT PARA HAZARD (Odoo 16 en Docker)
# Respalda: Base de datos PostgreSQL + Módulos Enterprise + Módulos Custom + Config
# Frecuencia: Cada 12 horas (cron)
# Retención local: 15 días
# Nota: Plesk sube estos archivos a Google Drive automáticamente
#       como parte del backup del dominio tesscorp.com.mx
# =============================================================

set -euo pipefail

# --- CONFIGURACIÓN ---
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BACKUP_NAME="backup_hazard_$(date +%Y%m%d_%H%M%S)"
BACKUP_DIR="$SCRIPT_DIR/backups"
CUSTOM_ADDONS_PATH="$SCRIPT_DIR/Addons/custom"
ENTERPRISE_ADDONS_PATH="$SCRIPT_DIR/Addons/enterprise"
CONF_PATH="$SCRIPT_DIR/Conf"
DOCKER_COMPOSE="$SCRIPT_DIR/docker-compose.yml"
DOCKERFILE="$SCRIPT_DIR/Dockerfile"
AGENTS_PATH="$SCRIPT_DIR/.agents"
DB_CONTAINER="odoo-16-db-hazard-new"
ODOO_CONTAINER="odoo-16-hazard-new"
DB_NAME="hazard_new"
DB_USER="odoo"
LOG_FILE="$SCRIPT_DIR/logs/backup.log"
MAX_RETENTION_DAYS=15
LOCK_FILE="/tmp/backup_hazard.lock"

# --- FUNCIONES ---
log() {
    echo "$1"
}

cleanup_on_exit() {
    rm -f "$LOCK_FILE"
    rm -f "$BACKUP_DIR/custom_$BACKUP_NAME.tar.gz" 2>/dev/null
    rm -f "$BACKUP_DIR/enterprise_$BACKUP_NAME.tar.gz" 2>/dev/null
    rm -f "$BACKUP_DIR/config_$BACKUP_NAME.tar.gz" 2>/dev/null
    rm -f "$BACKUP_DIR/db_$BACKUP_NAME.sql" 2>/dev/null
}

trap cleanup_on_exit EXIT

# --- PREVENIR EJECUCIONES SIMULTÁNEAS ---
if [ -f "$LOCK_FILE" ]; then
    LOCK_PID=$(cat "$LOCK_FILE" 2>/dev/null)
    if kill -0 "$LOCK_PID" 2>/dev/null; then
        log "⚠️ [$(date '+%Y-%m-%d %H:%M:%S')] Backup ya en ejecución (PID: $LOCK_PID). Saliendo."
        exit 1
    else
        log "🔓 [$(date '+%Y-%m-%d %H:%M:%S')] Lock file huérfano encontrado. Limpiando..."
        rm -f "$LOCK_FILE"
    fi
fi
echo $$ > "$LOCK_FILE"

# --- CREAR DIRECTORIOS ---
mkdir -p "$BACKUP_DIR"
mkdir -p "$(dirname "$LOG_FILE")"

log "🚀 [$(date '+%Y-%m-%d %H:%M:%S')] Iniciando respaldo total de Hazard..."

# --- VERIFICAR QUE LOS CONTENEDORES ESTÉN CORRIENDO ---
if ! docker ps --format '{{.Names}}' | grep -q "^${DB_CONTAINER}$"; then
    log "❌ [$(date '+%Y-%m-%d %H:%M:%S')] ERROR: Contenedor $DB_CONTAINER no está corriendo. Abortando."
    exit 1
fi

if ! docker ps --format '{{.Names}}' | grep -q "^${ODOO_CONTAINER}$"; then
    log "⚠️ [$(date '+%Y-%m-%d %H:%M:%S')] ADVERTENCIA: Contenedor $ODOO_CONTAINER no está corriendo. Continuando solo con DB..."
fi

# --- 1. RESPALDAR MÓDULOS CUSTOM ---
log "📦 Comprimiendo módulos custom..."
if [ -d "$CUSTOM_ADDONS_PATH" ]; then
    tar -czf "$BACKUP_DIR/custom_$BACKUP_NAME.tar.gz" -C "$(dirname "$CUSTOM_ADDONS_PATH")" "$(basename "$CUSTOM_ADDONS_PATH")"
    CUSTOM_SIZE=$(du -sh "$BACKUP_DIR/custom_$BACKUP_NAME.tar.gz" | cut -f1)
    log "   ✓ Módulos custom comprimidos: $CUSTOM_SIZE"
else
    log "⚠️ ADVERTENCIA: Ruta de módulos custom no encontrada: $CUSTOM_ADDONS_PATH"
fi

# --- 1b. RESPALDAR MÓDULOS ENTERPRISE ---
log "📦 Comprimiendo módulos Enterprise (esto puede tardar)..."
if [ -d "$ENTERPRISE_ADDONS_PATH" ]; then
    tar -czf "$BACKUP_DIR/enterprise_$BACKUP_NAME.tar.gz" -C "$(dirname "$ENTERPRISE_ADDONS_PATH")" "$(basename "$ENTERPRISE_ADDONS_PATH")"
    ENT_SIZE=$(du -sh "$BACKUP_DIR/enterprise_$BACKUP_NAME.tar.gz" | cut -f1)
    log "   ✓ Módulos Enterprise comprimidos: $ENT_SIZE"
else
    log "⚠️ ADVERTENCIA: Ruta de módulos Enterprise no encontrada: $ENTERPRISE_ADDONS_PATH"
fi

# --- 1c. RESPALDAR CONFIGURACIÓN (Docker + Odoo + Agents) ---
log "📦 Comprimiendo configuración del proyecto..."
tar -czf "$BACKUP_DIR/config_$BACKUP_NAME.tar.gz" \
    -C "$SCRIPT_DIR" \
    "$(basename "$CONF_PATH")" \
    "$(basename "$DOCKER_COMPOSE")" \
    "$(basename "$DOCKERFILE")" \
    "$(basename "$AGENTS_PATH")" \
    2>/dev/null
CONF_SIZE=$(du -sh "$BACKUP_DIR/config_$BACKUP_NAME.tar.gz" | cut -f1)
log "   ✓ Configuración comprimida: $CONF_SIZE"

# --- 2. RESPALDAR BASE DE DATOS (SQL Dump) ---
log "🗄️ Extrayendo base de datos desde el contenedor Docker..."
if docker exec "$DB_CONTAINER" pg_dump -U "$DB_USER" "$DB_NAME" > "$BACKUP_DIR/db_$BACKUP_NAME.sql" 2>/dev/null; then
    DB_SIZE=$(du -sh "$BACKUP_DIR/db_$BACKUP_NAME.sql" | cut -f1)
    log "   ✓ Base de datos exportada: $DB_SIZE"
else
    log "❌ [$(date '+%Y-%m-%d %H:%M:%S')] ERROR: Falló el dump de la base de datos."
    exit 1
fi

# --- 3. VERIFICAR QUE EL DUMP NO ESTÉ VACÍO ---
if [ ! -s "$BACKUP_DIR/db_$BACKUP_NAME.sql" ]; then
    log "❌ [$(date '+%Y-%m-%d %H:%M:%S')] ERROR: El dump de la base de datos está vacío. Abortando."
    exit 1
fi

# --- 4. EMPAQUETAR TODO ---
log "🎁 Creando paquete comprimido final..."
tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C "$BACKUP_DIR" \
    "custom_$BACKUP_NAME.tar.gz" \
    "enterprise_$BACKUP_NAME.tar.gz" \
    "config_$BACKUP_NAME.tar.gz" \
    "db_$BACKUP_NAME.sql"

FINAL_SIZE=$(du -sh "$BACKUP_DIR/$BACKUP_NAME.tar.gz" | cut -f1)
log "   ✓ Paquete final: $FINAL_SIZE"

# --- 5. VERIFICAR INTEGRIDAD DEL ARCHIVO ---
if tar -tzf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" > /dev/null 2>&1; then
    log "   ✓ Integridad verificada: OK"
else
    log "❌ [$(date '+%Y-%m-%d %H:%M:%S')] ERROR: El archivo de backup está corrupto."
    rm -f "$BACKUP_DIR/$BACKUP_NAME.tar.gz"
    exit 1
fi

# Limpiar archivos temporales (también se limpian en trap EXIT)
rm -f "$BACKUP_DIR/custom_$BACKUP_NAME.tar.gz" "$BACKUP_DIR/enterprise_$BACKUP_NAME.tar.gz" "$BACKUP_DIR/config_$BACKUP_NAME.tar.gz" "$BACKUP_DIR/db_$BACKUP_NAME.sql"

# --- 6. POLÍTICA DE RETENCIÓN ---
log "🧹 Ejecutando política de retención (Limpiando archivos de más de $MAX_RETENTION_DAYS días)..."
DELETED_COUNT=$(find "$BACKUP_DIR" -name "backup_hazard_*.tar.gz" -type f -mtime +$MAX_RETENTION_DAYS -delete -print | wc -l)
log "   ✓ Archivos eliminados: $DELETED_COUNT"

# --- 7. RESUMEN ---
TOTAL_BACKUPS=$(find "$BACKUP_DIR" -name "backup_hazard_*.tar.gz" -type f | wc -l)
TOTAL_SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)

echo "----------------------------------------------------"
log "✅ ¡RESPALDO COMPLETADO CON ÉXITO!"
log "📍 Archivo: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
log "📊 Tamaño: $FINAL_SIZE"
log "📁 Total backups locales: $TOTAL_BACKUPS ($TOTAL_SIZE)"
log "☁️  Google Drive: Plesk subirá este archivo en su próximo backup programado"
echo "----------------------------------------------------"
