#!/bin/bash
set -euo pipefail

## Contraseña del repositorio restic: maverick-backup-2024
## Fichero: /root/.restic-password (chmod 600)

## Variables
readonly RESTIC_REPOSITORY=/sustancia/backup/maverick-restic
readonly RESTIC_PASSWORD_FILE=/root/.restic-password
readonly BACKUP_MOUNT=/sustancia/backup
readonly LOG="${BACKUP_MOUNT}/backup_maverick.log"
readonly BACKUP_HOME=/home/sergio
readonly BACKUP_DOCKER=/home/sergio/docker
readonly BACKUP_DOCKER_VOLUMES=/var/volumes

export RESTIC_REPOSITORY RESTIC_PASSWORD_FILE

RUNNING_CONTAINERS=""

cleanup() {
    local exit_code=$?
    if [ -n "$RUNNING_CONTAINERS" ]; then
        printf "\n\n>> ARRANCANDO CONTENEDORES (cleanup)\n" | tee -a "${LOG}"
        echo "$RUNNING_CONTAINERS" | xargs docker start | tee -a "${LOG}"
    fi
    umount "$BACKUP_MOUNT" 2>/dev/null || true
    if [ $exit_code -ne 0 ]; then
        printf "\n\nBACKUP FALLIDO (código: %d)\n" "$exit_code" | tee -a "${LOG}"
    fi
}
trap cleanup EXIT

log_section() {
    printf "\n\n>> %s [%s]\n" "$1" "$(date +"%T")" | tee -a "${LOG}"
}

## Monta la carpeta del nas
mountpoint -q "$BACKUP_MOUNT" || mount "$BACKUP_MOUNT"

if ! mountpoint -q "$BACKUP_MOUNT"; then
    printf "No se ha podido montar %s\n" "$BACKUP_MOUNT" >&2
    exit 1
fi

## Rotar log: renombrar el actual con timestamp y conservar los últimos 5
if [ -f "${LOG}" ]; then
    mv "${LOG}" "${LOG}.$(date +%Y%m%d_%H%M%S)"
    find "${BACKUP_MOUNT}" -maxdepth 1 -name 'backup_maverick.log.*' -printf '%T@ %p\n' \
        | sort -rn | tail -n +6 | awk '{print $2}' | xargs -r rm --
fi

## Inicializar repo si no existe
if ! restic snapshots &>/dev/null; then
    restic init
fi

## Empieza el proceso de backup
SCRIPT_START=$(date +%s)
printf "\n\nCOMIENZA LA COPIA DE SEGURIDAD (%s)\n" "$(date +"%d-%m-%Y %T")" | tee -a "${LOG}"

## Backup de ficheros del sistema
log_section "COPIANDO FICHEROS DEL SISTEMA"
SYSTEM_PATHS=()
for p in /etc/cron.d /etc/cron.daily /etc/cron.hourly /etc/cron.monthly \
          /etc/cron.weekly /etc/crontab /etc/fstab; do
    [ -e "$p" ] && SYSTEM_PATHS+=("$p")
done
if [ ${#SYSTEM_PATHS[@]} -gt 0 ]; then
    restic backup "${SYSTEM_PATHS[@]}" --tag sistema | tee -a "${LOG}"
fi

## Backup de ficheros home
log_section "COPIANDO FICHEROS HOME"
HOME_FILES=()
for f in ".gitconfig" ".git-credentials" ".ssh"; do
    [ -e "${BACKUP_HOME}/${f}" ] && HOME_FILES+=("${BACKUP_HOME}/${f}")
done
if [ ${#HOME_FILES[@]} -gt 0 ]; then
    restic backup "${HOME_FILES[@]}" --tag home | tee -a "${LOG}"
fi

## Parar contenedores Docker
log_section "DETENIENDO CONTENEDORES"
RUNNING_CONTAINERS=$(docker ps -q)
if [ -n "$RUNNING_CONTAINERS" ]; then
    echo "$RUNNING_CONTAINERS" | xargs docker stop | tee -a "${LOG}"
else
    printf "No hay contenedores en ejecución\n" | tee -a "${LOG}"
fi

## Backup de docker compose y volúmenes
log_section "COPIANDO DOCKER"
DOCKER_PATHS=()
[ -d "${BACKUP_DOCKER}" ] && DOCKER_PATHS+=("${BACKUP_DOCKER}")
[ -d "${BACKUP_DOCKER_VOLUMES}" ] && DOCKER_PATHS+=("${BACKUP_DOCKER_VOLUMES}")
if [ ${#DOCKER_PATHS[@]} -gt 0 ]; then
    restic backup "${DOCKER_PATHS[@]}" --tag docker | tee -a "${LOG}"
fi

## Retención: eliminar snapshots antiguos
log_section "LIMPIEZA DE SNAPSHOTS ANTIGUOS"
restic forget \
    --keep-daily 7 \
    --keep-weekly 4 \
    --keep-monthly 6 \
    --prune | tee -a "${LOG}"

ELAPSED=$(( $(date +%s) - SCRIPT_START ))
printf "\n\nBACKUP COMPLETADO correctamente en %dm %ds\n" \
    "$((ELAPSED/60))" "$((ELAPSED%60))" | tee -a "${LOG}"
