#!/bin/bash
# ============================================
# Wordly.art - PostgreSQL Backup to NAS
# ============================================
# CRON: Run daily at 03:00
# 0 3 * * * /opt/wordly/scripts/backup-to-nas.sh >> /var/log/wordly-backup.log 2>&1
#
# Usage:
#   ./backup-to-nas.sh                    # Default: daily backup
#   ./backup-to-nas.sh --full             # Full backup with upload cleanup
#   ./backup-to-nas.sh --restore FILE     # Restore from specific backup
# ============================================

set -euo pipefail

# ===========================================
# CONFIGURATION - MODIFY THESE VALUES
# ===========================================
# NAS settings (SMB/CIFS or NFS mount point)
NAS_BACKUP_DIR="/mnt/nas-backups/wordly"

# Docker container name for PostgreSQL
POSTGRES_CONTAINER="wordly-postgres"
POSTGRES_USER="translate"
POSTGRES_DB="translate_db"
POSTGRES_PASSWORD="yLLgkEvt6mvzGDdoqtQvI1vEgMmR-W75ZTPW5StaIAU"

# Backup retention
DAILY_RETENTION=7      # Keep 7 daily backups
WEEKLY_RETENTION=4     # Keep 4 weekly backups
MONTHLY_RETENTION=6    # Keep 6 monthly backups

# Notification (optional - leave empty to disable)
NOTIFICATION_WEBHOOK=""  # Slack/Discord webhook URL

# ===========================================
# INTERNALS
# ===========================================
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
DATE_ONLY=$(date +"%Y-%m-%d")
DAY_OF_WEEK=$(date +"%u")    # 1=Mon, 7=Sun
DAY_OF_MONTH=$(date +"%d")
BACKUP_NAME="wordly_db_${TIMESTAMP}.sql.gz"
BACKUP_PATH="${NAS_BACKUP_DIR}/${BACKUP_NAME}"
LOG_PREFIX="[Wordly Backup ${TIMESTAMP}]"

# Colors for terminal output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m'

# ===========================================
# FUNCTIONS
# ===========================================

log() {
    echo "${LOG_PREFIX} $1"
}

log_success() {
    echo -e "${LOG_PREFIX} ${GREEN}$1${NC}"
}

log_error() {
    echo -e "${LOG_PREFIX} ${RED}ERROR: $1${NC}"
}

log_warning() {
    echo -e "${LOG_PREFIX} ${YELLOW}WARNING: $1${NC}"
}

send_notification() {
    local message="$1"
    if [ -n "${NOTIFICATION_WEBHOOK}" ]; then
        curl -s -X POST "${NOTIFICATION_WEBHOOK}" \
            -H "Content-Type: application/json" \
            -d "{\"text\": \"${message}\"}" > /dev/null 2>&1 || true
    fi
}

check_prerequisites() {
    # Check NAS mount
    if [ ! -d "${NAS_BACKUP_DIR}" ]; then
        log_error "NAS backup directory not found: ${NAS_BACKUP_DIR}"
        log "Attempting to mount NAS..."

        # Try to mount if configured via /etc/fstab
        mount "${NAS_BACKUP_DIR}" 2>/dev/null || true

        if [ ! -d "${NAS_BACKUP_DIR}" ]; then
            log_error "Cannot mount NAS. Aborting."
            send_notification "Wordly Backup FAILED: NAS not mounted at ${NAS_BACKUP_DIR}"
            exit 1
        fi
    fi

    # Check Docker
    if ! docker ps --format '{{.Names}}' | grep -q "${POSTGRES_CONTAINER}"; then
        log_error "PostgreSQL container '${POSTGRES_CONTAINER}' is not running."
        send_notification "Wordly Backup FAILED: PostgreSQL container not running"
        exit 1
    fi

    log_success "Prerequisites OK"
}

create_backup() {
    log "Starting backup of '${POSTGRES_DB}'..."

    # Create backup directory structure
    mkdir -p "${NAS_BACKUP_DIR}/daily"
    mkdir -p "${NAS_BACKUP_DIR}/weekly"
    mkdir -p "${NAS_BACKUP_DIR}/monthly"

    # Run pg_dump inside Docker container
    docker exec "${POSTGRES_CONTAINER}" pg_dump \
        -U "${POSTGRES_USER}" \
        -d "${POSTGRES_DB}" \
        --format=custom \
        --compress=9 \
        --no-owner \
        --no-acl \
        2>/dev/null | gzip > "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}"

    local backup_size=$(du -h "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}" | cut -f1)

    if [ -f "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}" ]; then
        log_success "Backup created: ${BACKUP_NAME} (${backup_size})"

        # Copy to weekly/monthly if applicable
        if [ "${DAY_OF_WEEK}" = "7" ]; then
            cp "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}" "${NAS_BACKUP_DIR}/weekly/"
            log "Weekly backup copied"
        fi

        if [ "${DAY_OF_MONTH}" = "01" ]; then
            cp "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}" "${NAS_BACKUP_DIR}/monthly/"
            log "Monthly backup copied"
        fi

        send_notification "Wordly Backup SUCCESS: ${BACKUP_NAME} (${backup_size})"
    else
        log_error "Backup file was not created!"
        send_notification "Wordly Backup FAILED: pg_dump produced no output"
        exit 1
    fi
}

cleanup_old_backups() {
    log "Cleaning up old backups..."

    # Daily: keep last N days
    local daily_count=$(ls -1 "${NAS_BACKUP_DIR}/daily/" 2>/dev/null | wc -l)
    if [ "${daily_count}" -gt "${DAILY_RETENTION}" ]; then
        ls -1t "${NAS_BACKUP_DIR}/daily/" | tail -n +$((DAILY_RETENTION + 1)) | while read -r f; do
            rm -f "${NAS_BACKUP_DIR}/daily/${f}"
            log "  Deleted daily: ${f}"
        done
    fi

    # Weekly: keep last N weeks
    local weekly_count=$(ls -1 "${NAS_BACKUP_DIR}/weekly/" 2>/dev/null | wc -l)
    if [ "${weekly_count}" -gt "${WEEKLY_RETENTION}" ]; then
        ls -1t "${NAS_BACKUP_DIR}/weekly/" | tail -n +$((WEEKLY_RETENTION + 1)) | while read -r f; do
            rm -f "${NAS_BACKUP_DIR}/weekly/${f}"
            log "  Deleted weekly: ${f}"
        done
    fi

    # Monthly: keep last N months
    local monthly_count=$(ls -1 "${NAS_BACKUP_DIR}/monthly/" 2>/dev/null | wc -l)
    if [ "${monthly_count}" -gt "${MONTHLY_RETENTION}" ]; then
        ls -1t "${NAS_BACKUP_DIR}/monthly/" | tail -n +$((MONTHLY_RETENTION + 1)) | while read -r f; do
            rm -f "${NAS_BACKUP_DIR}/monthly/${f}"
            log "  Deleted monthly: ${f}"
        done
    fi

    log_success "Cleanup done"
}

verify_backup() {
    log "Verifying backup integrity..."

    if gzip -t "${NAS_BACKUP_DIR}/daily/${BACKUP_NAME}" 2>/dev/null; then
        log_success "Backup integrity OK"
    else
        log_error "Backup integrity check FAILED!"
        send_notification "Wordly Backup WARNING: Integrity check failed for ${BACKUP_NAME}"
        # Don't delete - let admin investigate
    fi
}

restore_backup() {
    local backup_file="$1"

    if [ -z "${backup_file}" ]; then
        log_error "Usage: $0 --restore <backup_file>"
        echo ""
        echo "Available backups:"
        echo "=== Daily ==="
        ls -lht "${NAS_BACKUP_DIR}/daily/" 2>/dev/null || echo "  (none)"
        echo "=== Weekly ==="
        ls -lht "${NAS_BACKUP_DIR}/weekly/" 2>/dev/null || echo "  (none)"
        echo "=== Monthly ==="
        ls -lht "${NAS_BACKUP_DIR}/monthly/" 2>/dev/null || echo "  (none)"
        exit 1
    fi

    # Find the file
    local full_path=""
    for dir in daily weekly monthly; do
        if [ -f "${NAS_BACKUP_DIR}/${dir}/${backup_file}" ]; then
            full_path="${NAS_BACKUP_DIR}/${dir}/${backup_file}"
            break
        fi
    done

    if [ -z "${full_path}" ]; then
        log_error "Backup file not found: ${backup_file}"
        exit 1
    fi

    echo ""
    log_warning "RESTORE MODE - This will OVERWRITE the current database!"
    echo "  File: ${full_path}"
    echo "  Database: ${POSTGRES_DB}"
    echo ""
    read -p "Are you sure? Type 'YES' to confirm: " confirm

    if [ "${confirm}" != "YES" ]; then
        log "Restore cancelled."
        exit 0
    fi

    log "Restoring from ${full_path}..."

    # Create a safety backup first
    log "Creating safety backup before restore..."
    SAFETY_NAME="wordly_db_pre_restore_${TIMESTAMP}.sql.gz"
    docker exec "${POSTGRES_CONTAINER}" pg_dump \
        -U "${POSTGRES_USER}" \
        -d "${POSTGRES_DB}" \
        --format=custom \
        --compress=9 \
        2>/dev/null | gzip > "${NAS_BACKUP_DIR}/daily/${SAFETY_NAME}"
    log "Safety backup: ${SAFETY_NAME}"

    # Restore
    gunzip -c "${full_path}" | docker exec -i "${POSTGRES_CONTAINER}" \
        pg_restore \
        -U "${POSTGRES_USER}" \
        -d "${POSTGRES_DB}" \
        --clean \
        --if-exists \
        --no-owner \
        --no-acl \
        2>/dev/null || true

    log_success "Restore completed!"
    log_warning "Restart backend: docker restart wordly-backend"
}

# ===========================================
# MAIN
# ===========================================

case "${1:-}" in
    --restore)
        restore_backup "${2:-}"
        ;;
    --full)
        check_prerequisites
        create_backup
        verify_backup
        cleanup_old_backups
        log_success "Full backup cycle complete!"
        ;;
    *)
        check_prerequisites
        create_backup
        verify_backup
        cleanup_old_backups
        log_success "Backup complete!"
        ;;
esac
