#!/bin/bash

# Laravel Timebank Backup Cleanup Script
# Cleans up old backups based on retention policies and monitors disk usage
# Usage: ./cleanup-backups.sh [options]
# Options: --dry-run, --force, --verbose

set -e  # Exit on any error

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
BACKUP_ROOT_DIR="$PROJECT_ROOT/backups"
LOG_FILE="$BACKUP_ROOT_DIR/backup.log"

# Configuration file path
CONFIG_FILE="$SCRIPT_DIR/backup-retention.conf"

# Default retention policies (days) - used as fallback if config file is missing or invalid
DEFAULT_DAILY_RETENTION=7
DEFAULT_WEEKLY_RETENTION=28    # 4 weeks
DEFAULT_MONTHLY_RETENTION=365  # 12 months
DEFAULT_PRE_RESTORE_RETENTION=30
DEFAULT_LOG_RETENTION=30

# Default count limits - used as fallback
DEFAULT_DAILY_COUNT_LIMIT=7
DEFAULT_WEEKLY_COUNT_LIMIT=4
DEFAULT_MONTHLY_COUNT_LIMIT=12
DEFAULT_PRE_RESTORE_COUNT_LIMIT=5
DEFAULT_SNAPSHOT_COUNT_LIMIT=3

# Default disk usage thresholds
DEFAULT_DISK_WARNING_THRESHOLD=85  # Warn at 85% disk usage
DEFAULT_DISK_CRITICAL_THRESHOLD=95 # Force cleanup at 95% disk usage

# Default settings
DEFAULT_EMAIL_NOTIFICATIONS_ENABLED=true
DEFAULT_CLEANUP_MODE="both"
DEFAULT_CLEANUP_EMPTY_DIRS=true
DEFAULT_VERIFY_BEFORE_DELETE=false

# Function to load configuration with validation and fallbacks
load_config() {
    # Set defaults first
    DAILY_RETENTION=$DEFAULT_DAILY_RETENTION
    WEEKLY_RETENTION=$DEFAULT_WEEKLY_RETENTION
    MONTHLY_RETENTION=$DEFAULT_MONTHLY_RETENTION
    PRE_RESTORE_RETENTION=$DEFAULT_PRE_RESTORE_RETENTION
    LOG_RETENTION=$DEFAULT_LOG_RETENTION
    
    DAILY_COUNT_LIMIT=$DEFAULT_DAILY_COUNT_LIMIT
    WEEKLY_COUNT_LIMIT=$DEFAULT_WEEKLY_COUNT_LIMIT
    MONTHLY_COUNT_LIMIT=$DEFAULT_MONTHLY_COUNT_LIMIT
    PRE_RESTORE_COUNT_LIMIT=$DEFAULT_PRE_RESTORE_COUNT_LIMIT
    SNAPSHOT_COUNT_LIMIT=$DEFAULT_SNAPSHOT_COUNT_LIMIT
    
    DISK_WARNING_THRESHOLD=$DEFAULT_DISK_WARNING_THRESHOLD
    DISK_CRITICAL_THRESHOLD=$DEFAULT_DISK_CRITICAL_THRESHOLD
    
    EMAIL_NOTIFICATIONS_ENABLED=$DEFAULT_EMAIL_NOTIFICATIONS_ENABLED
    CLEANUP_MODE=$DEFAULT_CLEANUP_MODE
    CLEANUP_EMPTY_DIRS=$DEFAULT_CLEANUP_EMPTY_DIRS
    VERIFY_BEFORE_DELETE=$DEFAULT_VERIFY_BEFORE_DELETE
    
    # Load config file if it exists
    if [ -f "$CONFIG_FILE" ]; then
        log "INFO" "Loading retention configuration from: $CONFIG_FILE"
        
        # Source the config file with error handling
        if source "$CONFIG_FILE" 2>/dev/null; then
            log "INFO" "Configuration loaded successfully"
            
            # Validate numeric values and reset to defaults if invalid
            validate_numeric "DAILY_RETENTION" "$DEFAULT_DAILY_RETENTION" 1 365
            validate_numeric "WEEKLY_RETENTION" "$DEFAULT_WEEKLY_RETENTION" 1 730
            validate_numeric "MONTHLY_RETENTION" "$DEFAULT_MONTHLY_RETENTION" 1 2555  # ~7 years
            validate_numeric "PRE_RESTORE_RETENTION" "$DEFAULT_PRE_RESTORE_RETENTION" 1 365
            validate_numeric "LOG_RETENTION" "$DEFAULT_LOG_RETENTION" 1 365
            
            validate_numeric "DAILY_COUNT_LIMIT" "$DEFAULT_DAILY_COUNT_LIMIT" 1 100
            validate_numeric "WEEKLY_COUNT_LIMIT" "$DEFAULT_WEEKLY_COUNT_LIMIT" 1 100
            validate_numeric "MONTHLY_COUNT_LIMIT" "$DEFAULT_MONTHLY_COUNT_LIMIT" 1 100
            validate_numeric "PRE_RESTORE_COUNT_LIMIT" "$DEFAULT_PRE_RESTORE_COUNT_LIMIT" 1 50
            validate_numeric "SNAPSHOT_COUNT_LIMIT" "$DEFAULT_SNAPSHOT_COUNT_LIMIT" 1 20
            
            validate_numeric "DISK_WARNING_THRESHOLD" "$DEFAULT_DISK_WARNING_THRESHOLD" 50 99
            validate_numeric "DISK_CRITICAL_THRESHOLD" "$DEFAULT_DISK_CRITICAL_THRESHOLD" 60 100
            
            # Ensure critical threshold is higher than warning threshold
            if [ $DISK_CRITICAL_THRESHOLD -le $DISK_WARNING_THRESHOLD ]; then
                log "WARNING" "Critical threshold ($DISK_CRITICAL_THRESHOLD%) must be higher than warning threshold ($DISK_WARNING_THRESHOLD%). Resetting to defaults."
                DISK_WARNING_THRESHOLD=$DEFAULT_DISK_WARNING_THRESHOLD
                DISK_CRITICAL_THRESHOLD=$DEFAULT_DISK_CRITICAL_THRESHOLD
            fi
            
            # Validate boolean values
            validate_boolean "EMAIL_NOTIFICATIONS_ENABLED" "$DEFAULT_EMAIL_NOTIFICATIONS_ENABLED"
            validate_boolean "CLEANUP_EMPTY_DIRS" "$DEFAULT_CLEANUP_EMPTY_DIRS"
            validate_boolean "VERIFY_BEFORE_DELETE" "$DEFAULT_VERIFY_BEFORE_DELETE"
            
            # Validate cleanup mode
            if [[ ! "$CLEANUP_MODE" =~ ^(age_only|count_only|both)$ ]]; then
                log "WARNING" "Invalid CLEANUP_MODE: $CLEANUP_MODE. Using default: $DEFAULT_CLEANUP_MODE"
                CLEANUP_MODE=$DEFAULT_CLEANUP_MODE
            fi
            
        else
            log "WARNING" "Error loading config file. Using default values."
        fi
    else
        log "INFO" "Config file not found: $CONFIG_FILE. Using default retention policies."
        log "INFO" "Run: cp $CONFIG_FILE.example $CONFIG_FILE to create a customizable config file."
    fi
}

# Function to validate numeric configuration values
validate_numeric() {
    local var_name="$1"
    local default_val="$2"
    local min_val="$3"
    local max_val="$4"
    
    local current_val
    eval "current_val=\$$var_name"
    
    # Check if it's a valid number
    if ! [[ "$current_val" =~ ^[0-9]+$ ]]; then
        log "WARNING" "Invalid $var_name: '$current_val'. Using default: $default_val"
        eval "$var_name=$default_val"
        return
    fi
    
    # Check range
    if [ "$current_val" -lt "$min_val" ] || [ "$current_val" -gt "$max_val" ]; then
        log "WARNING" "$var_name ($current_val) out of range ($min_val-$max_val). Using default: $default_val"
        eval "$var_name=$default_val"
    fi
}

# Function to validate boolean configuration values
validate_boolean() {
    local var_name="$1"
    local default_val="$2"
    
    local current_val
    eval "current_val=\$$var_name"
    
    # Normalize to lowercase
    current_val=$(echo "$current_val" | tr '[:upper:]' '[:lower:]')
    
    case "$current_val" in
        true|yes|1|on)
            eval "$var_name=true"
            ;;
        false|no|0|off)
            eval "$var_name=false"
            ;;
        *)
            log "WARNING" "Invalid $var_name: '$current_val'. Using default: $default_val"
            eval "$var_name=$default_val"
            ;;
    esac
}

# Create log directory
mkdir -p "$BACKUP_ROOT_DIR/logs"

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

# Logging function
log() {
    local level="$1"
    local message="$2"
    local timestamp="[$(date '+%Y-%m-%d %H:%M:%S')]"
    
    case "$level" in
        "INFO")
            echo -e "${timestamp} ${BLUE}[INFO]${NC} $message" | tee -a "$LOG_FILE"
            ;;
        "SUCCESS")
            echo -e "${timestamp} ${GREEN}[SUCCESS]${NC} $message" | tee -a "$LOG_FILE"
            ;;
        "WARNING")
            echo -e "${timestamp} ${YELLOW}[WARNING]${NC} $message" | tee -a "$LOG_FILE"
            ;;
        "ERROR")
            echo -e "${timestamp} ${RED}[ERROR]${NC} $message" | tee -a "$LOG_FILE"
            ;;
        *)
            echo "$timestamp $message" | tee -a "$LOG_FILE"
            ;;
    esac
}

# Function to send email notifications
send_notification() {
    local subject="$1"
    local message="$2"
    
    # Check if email notifications are enabled
    if [ "$EMAIL_NOTIFICATIONS_ENABLED" != "true" ]; then
        log "INFO" "Email notifications disabled in config, skipping: $subject"
        return 0
    fi
    
    if command -v mail >/dev/null 2>&1; then
        echo "$message" | mail -s "$subject" "${BACKUP_NOTIFY_EMAIL:-$USER@localhost}" 2>/dev/null || true
        log "INFO" "Email notification sent: $subject"
    else
        log "WARNING" "Mail command not available, notification not sent"
    fi
}

# Function to show usage
show_usage() {
    # Load config to show current values
    load_config
    
    echo "Usage: $0 [options]"
    echo ""
    echo "Options:"
    echo "  --dry-run     - Show what would be deleted without actually deleting"
    echo "  --force       - Force cleanup even if disk usage is not critical"
    echo "  --verbose     - Show detailed information"
    echo "  --help        - Show this help message"
    echo ""
    echo "Current Configuration:"
    echo "  Config file:        $CONFIG_FILE"
    if [ -f "$CONFIG_FILE" ]; then
        echo "  Config status:      Loaded"
    else
        echo "  Config status:      Using defaults (file not found)"
    fi
    echo ""
    echo "Time-based Retention (days):"
    echo "  Daily backups:      $DAILY_RETENTION days"
    echo "  Weekly backups:     $WEEKLY_RETENTION days"
    echo "  Monthly backups:    $MONTHLY_RETENTION days"
    echo "  Pre-restore:        $PRE_RESTORE_RETENTION days"
    echo "  Log files:          $LOG_RETENTION days"
    echo ""
    echo "Count-based Retention (keep N most recent):"
    echo "  Daily backups:      $DAILY_COUNT_LIMIT files"
    echo "  Weekly backups:     $WEEKLY_COUNT_LIMIT files"
    echo "  Monthly backups:    $MONTHLY_COUNT_LIMIT files"
    echo "  Pre-restore:        $PRE_RESTORE_COUNT_LIMIT files"
    echo "  Storage snapshots:  $SNAPSHOT_COUNT_LIMIT files"
    echo ""
    echo "Disk Space Thresholds:"
    echo "  Warning threshold:  $DISK_WARNING_THRESHOLD%"
    echo "  Critical threshold: $DISK_CRITICAL_THRESHOLD%"
    echo ""
    echo "Settings:"
    echo "  Email notifications: $EMAIL_NOTIFICATIONS_ENABLED"
    echo "  Cleanup mode:       $CLEANUP_MODE"
    echo "  Clean empty dirs:   $CLEANUP_EMPTY_DIRS"
    echo "  Verify before delete: $VERIFY_BEFORE_DELETE"
    echo ""
    echo "To customize retention policies:"
    echo "  Edit: $CONFIG_FILE"
    echo ""
    exit 0
}

# Function to check disk usage
check_disk_usage() {
    local backup_dir="$1"
    local disk_usage=$(df "$backup_dir" | awk 'NR==2 {print substr($5,1,length($5)-1)}')
    
    echo "$disk_usage"
}

# Function to get human readable size
get_size() {
    local path="$1"
    if [ -f "$path" ]; then
        du -h "$path" | cut -f1
    elif [ -d "$path" ]; then
        du -sh "$path" | cut -f1
    else
        echo "0B"
    fi
}

# Function to cleanup old backups by age
cleanup_by_age() {
    local backup_dir="$1"
    local retention_days="$2"
    local backup_type="$3"
    local pattern="$4"
    local dry_run="$5"
    
    if [ ! -d "$backup_dir" ]; then
        return 0
    fi
    
    log "INFO" "Cleaning up $backup_type backups older than $retention_days days"
    
    local files_found=0
    local files_deleted=0
    local total_size_deleted=0
    
    # Find files older than retention period
    while IFS= read -r -d '' backup_file; do
        files_found=$((files_found + 1))
        local file_size_kb=$(du -k "$backup_file" | cut -f1)
        local file_size_hr=$(get_size "$backup_file")
        
        if [ "$dry_run" = true ]; then
            if [ "$VERBOSE" = true ]; then
                log "INFO" "Would delete: $(basename "$backup_file") ($file_size_hr)"
            fi
        else
            if [ "$VERBOSE" = true ]; then
                log "INFO" "Deleting: $(basename "$backup_file") ($file_size_hr)"
            fi
            rm "$backup_file"
            files_deleted=$((files_deleted + 1))
            total_size_deleted=$((total_size_deleted + file_size_kb))
        fi
    done < <(find "$backup_dir" -name "$pattern" -type f -mtime +$retention_days -print0 2>/dev/null)
    
    if [ $files_found -gt 0 ]; then
        local total_size_hr=$(echo "$total_size_deleted" | awk '{printf "%.1fMB", $1/1024}')
        if [ "$dry_run" = true ]; then
            log "INFO" "$backup_type: Would delete $files_found files ($total_size_hr)"
        else
            log "SUCCESS" "$backup_type: Deleted $files_deleted files ($total_size_hr)"
        fi
    else
        log "INFO" "$backup_type: No old files to clean up"
    fi
    
    return 0
}

# Function to cleanup by count (keep only N most recent)
cleanup_by_count() {
    local backup_dir="$1"
    local keep_count="$2"
    local backup_type="$3"
    local pattern="$4"
    local dry_run="$5"
    
    if [ ! -d "$backup_dir" ]; then
        return 0
    fi
    
    log "INFO" "Ensuring only $keep_count most recent $backup_type backups are kept"
    
    local files_to_delete=($(find "$backup_dir" -name "$pattern" -type f | sort -r | tail -n +$((keep_count + 1))))
    
    if [ ${#files_to_delete[@]} -gt 0 ]; then
        local total_size_deleted=0
        
        for backup_file in "${files_to_delete[@]}"; do
            local file_size_kb=$(du -k "$backup_file" | cut -f1)
            local file_size_hr=$(get_size "$backup_file")
            
            if [ "$dry_run" = true ]; then
                if [ "$VERBOSE" = true ]; then
                    log "INFO" "Would delete (count): $(basename "$backup_file") ($file_size_hr)"
                fi
            else
                if [ "$VERBOSE" = true ]; then
                    log "INFO" "Deleting (count): $(basename "$backup_file") ($file_size_hr)"
                fi
                rm "$backup_file"
                total_size_deleted=$((total_size_deleted + file_size_kb))
            fi
        done
        
        local total_size_hr=$(echo "$total_size_deleted" | awk '{printf "%.1fMB", $1/1024}')
        if [ "$dry_run" = true ]; then
            log "INFO" "$backup_type: Would delete ${#files_to_delete[@]} excess files ($total_size_hr)"
        else
            log "SUCCESS" "$backup_type: Deleted ${#files_to_delete[@]} excess files ($total_size_hr)"
        fi
    else
        log "INFO" "$backup_type: No excess files to clean up"
    fi
    
    return 0
}

# Function to clean up empty directories
cleanup_empty_dirs() {
    local backup_root="$1"
    local dry_run="$2"
    
    log "INFO" "Cleaning up empty directories"
    
    local empty_dirs=($(find "$backup_root" -type d -empty 2>/dev/null))
    
    if [ ${#empty_dirs[@]} -gt 0 ]; then
        for empty_dir in "${empty_dirs[@]}"; do
            # Skip the root backup directories
            if [[ "$empty_dir" =~ (database|storage|logs)$ ]]; then
                continue
            fi
            
            if [ "$dry_run" = true ]; then
                if [ "$VERBOSE" = true ]; then
                    log "INFO" "Would remove empty directory: $empty_dir"
                fi
            else
                if [ "$VERBOSE" = true ]; then
                    log "INFO" "Removing empty directory: $empty_dir"
                fi
                rmdir "$empty_dir" 2>/dev/null || true
            fi
        done
        
        if [ "$dry_run" = true ]; then
            log "INFO" "Would remove ${#empty_dirs[@]} empty directories"
        else
            log "SUCCESS" "Removed empty directories"
        fi
    else
        log "INFO" "No empty directories to clean up"
    fi
}

# Function to generate cleanup report
generate_report() {
    local backup_root="$1"
    
    log "INFO" "Backup storage report:"
    
    if [ -d "$backup_root" ]; then
        # Database backups
        if [ -d "$backup_root/database" ]; then
            local db_count=$(find "$backup_root/database" -name "*.sql.gz" | wc -l)
            local db_size=$(get_size "$backup_root/database")
            log "INFO" "  Database backups: $db_count files ($db_size)"
        fi
        
        # Storage backups
        if [ -d "$backup_root/storage" ]; then
            local storage_count=$(find "$backup_root/storage" -name "*.tar.gz" | wc -l)
            local storage_size=$(get_size "$backup_root/storage")
            log "INFO" "  Storage backups: $storage_count files ($storage_size)"
        fi
        
        # Total size
        local total_size=$(get_size "$backup_root")
        log "INFO" "  Total backup size: $total_size"
        
        # Disk usage
        local disk_usage=$(check_disk_usage "$backup_root")
        local available_space=$(df -h "$backup_root" | awk 'NR==2 {print $4}')
        log "INFO" "  Disk usage: ${disk_usage}% (${available_space} available)"
        
        # Oldest and newest backups
        local oldest_backup=$(find "$backup_root" -name "*.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | head -n 1 | cut -d' ' -f2-)
        local newest_backup=$(find "$backup_root" -name "*.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -n 1 | cut -d' ' -f2-)
        
        if [ -n "$oldest_backup" ]; then
            local oldest_date=$(date -r "$oldest_backup" '+%Y-%m-%d %H:%M:%S')
            log "INFO" "  Oldest backup: $(basename "$oldest_backup") ($oldest_date)"
        fi
        
        if [ -n "$newest_backup" ]; then
            local newest_date=$(date -r "$newest_backup" '+%Y-%m-%d %H:%M:%S')
            log "INFO" "  Newest backup: $(basename "$newest_backup") ($newest_date)"
        fi
    else
        log "WARNING" "No backup directory found"
    fi
}

# Parse command line arguments
DRY_RUN=false
FORCE=false
VERBOSE=false

while [[ $# -gt 0 ]]; do
    case $1 in
        --dry-run)
            DRY_RUN=true
            shift
            ;;
        --force)
            FORCE=true
            shift
            ;;
        --verbose)
            VERBOSE=true
            shift
            ;;
        --help)
            show_usage
            ;;
        *)
            log "ERROR" "Unknown option: $1"
            show_usage
            ;;
    esac
done

# Main execution
main() {
    # Load configuration before starting
    load_config
    
    log "INFO" "============================================"
    if [ "$DRY_RUN" = true ]; then
        log "INFO" "Starting backup cleanup (DRY RUN)"
    else
        log "INFO" "Starting backup cleanup"
    fi
    log "INFO" "Time: $(date)"
    log "INFO" "============================================"
    
    local start_time=$(date +%s)
    
    # Check if backup directory exists
    if [ ! -d "$BACKUP_ROOT_DIR" ]; then
        log "WARNING" "Backup directory not found: $BACKUP_ROOT_DIR"
        exit 0
    fi
    
    # Check disk usage
    local disk_usage=$(check_disk_usage "$BACKUP_ROOT_DIR")
    log "INFO" "Current disk usage: ${disk_usage}%"
    
    local should_cleanup=false
    
    if [ $disk_usage -ge $DISK_CRITICAL_THRESHOLD ]; then
        log "WARNING" "Disk usage critical (${disk_usage}% >= ${DISK_CRITICAL_THRESHOLD}%), forcing cleanup"
        send_notification "Timebank Cleanup Critical - Aggressive Cleanup Started" \
            "CRITICAL: Disk usage has reached ${disk_usage}% (>= ${DISK_CRITICAL_THRESHOLD}%)

Aggressive backup cleanup has been automatically triggered to free disk space.

Location: $BACKUP_ROOT_DIR
Current usage: ${disk_usage}%
Critical threshold: ${DISK_CRITICAL_THRESHOLD}%

Time: $(date)

This is an automated cleanup to prevent disk space issues. Please check the system if this occurs frequently."
        should_cleanup=true
    elif [ $disk_usage -ge $DISK_WARNING_THRESHOLD ]; then
        log "WARNING" "Disk usage high (${disk_usage}% >= ${DISK_WARNING_THRESHOLD}%)"
        send_notification "Timebank Cleanup Warning - Low Disk Space" \
            "WARNING: Disk usage is getting high at ${disk_usage}% (>= ${DISK_WARNING_THRESHOLD}%)

Backup cleanup will be performed to prevent potential disk space issues.

Location: $BACKUP_ROOT_DIR  
Current usage: ${disk_usage}%
Warning threshold: ${DISK_WARNING_THRESHOLD}%
Critical threshold: ${DISK_CRITICAL_THRESHOLD}%

Time: $(date)

Please monitor disk usage and consider expanding storage if warnings occur frequently."
        should_cleanup=true
    elif [ "$FORCE" = true ]; then
        log "INFO" "Force cleanup requested"
        should_cleanup=true
    else
        log "INFO" "Disk usage normal, running standard cleanup"
        should_cleanup=true
    fi
    
    if [ "$should_cleanup" = true ]; then
        # Cleanup database backups
        if [ -d "$BACKUP_ROOT_DIR/database" ]; then
            # Load environment for database name
            if [ -f "$PROJECT_ROOT/.env" ]; then
                source "$SCRIPT_DIR/load-env.sh"
                load_env "$PROJECT_ROOT/.env"
            fi
            
            local db_pattern="*.sql.gz"
            if [ -n "$DB_DATABASE" ]; then
                db_pattern="${DB_DATABASE}_*.sql.gz"
            fi
            
            cleanup_by_age "$BACKUP_ROOT_DIR/database/daily" $DAILY_RETENTION "daily database" "$db_pattern" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/database/weekly" $WEEKLY_RETENTION "weekly database" "$db_pattern" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/database/monthly" $MONTHLY_RETENTION "monthly database" "$db_pattern" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/database/pre-restore" $PRE_RESTORE_RETENTION "pre-restore database" "*.sql.gz" "$DRY_RUN"
            
            # Also enforce count limits
            cleanup_by_count "$BACKUP_ROOT_DIR/database/daily" $DAILY_COUNT_LIMIT "daily database" "$db_pattern" "$DRY_RUN"
            cleanup_by_count "$BACKUP_ROOT_DIR/database/weekly" $WEEKLY_COUNT_LIMIT "weekly database" "$db_pattern" "$DRY_RUN"
            cleanup_by_count "$BACKUP_ROOT_DIR/database/monthly" $MONTHLY_COUNT_LIMIT "monthly database" "$db_pattern" "$DRY_RUN"
        fi
        
        # Cleanup storage backups
        if [ -d "$BACKUP_ROOT_DIR/storage" ]; then
            cleanup_by_age "$BACKUP_ROOT_DIR/storage/daily" $DAILY_RETENTION "daily storage" "*.tar.gz" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/storage/weekly" $WEEKLY_RETENTION "weekly storage" "*.tar.gz" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/storage/monthly" $MONTHLY_RETENTION "monthly storage" "*.tar.gz" "$DRY_RUN"
            cleanup_by_age "$BACKUP_ROOT_DIR/storage/pre-restore" $PRE_RESTORE_RETENTION "pre-restore storage" "*.tar.gz" "$DRY_RUN"
            
            # Count limits for storage
            cleanup_by_count "$BACKUP_ROOT_DIR/storage/daily" $DAILY_COUNT_LIMIT "daily storage" "*.tar.gz" "$DRY_RUN"
            cleanup_by_count "$BACKUP_ROOT_DIR/storage/weekly" $WEEKLY_COUNT_LIMIT "weekly storage" "*.tar.gz" "$DRY_RUN"
            cleanup_by_count "$BACKUP_ROOT_DIR/storage/monthly" $MONTHLY_COUNT_LIMIT "monthly storage" "*.tar.gz" "$DRY_RUN"
            
            # Cleanup old snapshots
            cleanup_by_count "$BACKUP_ROOT_DIR/storage/snapshots" $SNAPSHOT_COUNT_LIMIT "storage snapshots" "*" "$DRY_RUN"
        fi
        
        # Cleanup empty directories
        cleanup_empty_dirs "$BACKUP_ROOT_DIR" "$DRY_RUN"
        
        # Cleanup old log files
        if [ -d "$BACKUP_ROOT_DIR/logs" ]; then
            cleanup_by_age "$BACKUP_ROOT_DIR/logs" $LOG_RETENTION "log files" "*.log" "$DRY_RUN"
        fi
    fi
    
    # Generate final report
    generate_report "$BACKUP_ROOT_DIR"
    
    # Calculate execution time
    local end_time=$(date +%s)
    local execution_time=$((end_time - start_time))
    local execution_time_formatted=$(date -d@$execution_time -u +%H:%M:%S)
    
    # Send completion summary email if cleanup was triggered by disk space conditions
    local final_disk_usage=$(check_disk_usage "$BACKUP_ROOT_DIR")
    if [ "$should_cleanup" = true ] && ([ $disk_usage -ge $DISK_WARNING_THRESHOLD ] || [ "$FORCE" = true ]); then
        local cleanup_type="Standard"
        if [ $disk_usage -ge $DISK_CRITICAL_THRESHOLD ]; then
            cleanup_type="Aggressive (Critical)"
        elif [ $disk_usage -ge $DISK_WARNING_THRESHOLD ]; then
            cleanup_type="Warning Level"
        elif [ "$FORCE" = true ]; then
            cleanup_type="Manual Force"
        fi
        
        # Get backup statistics
        local db_count=0
        local db_size="0B"
        local storage_count=0  
        local storage_size="0B"
        local total_size="Unknown"
        
        if [ -d "$BACKUP_ROOT_DIR/database" ]; then
            db_count=$(find "$BACKUP_ROOT_DIR/database" -name "*.sql.gz" 2>/dev/null | wc -l)
            db_size=$(get_size "$BACKUP_ROOT_DIR/database")
        fi
        
        if [ -d "$BACKUP_ROOT_DIR/storage" ]; then
            storage_count=$(find "$BACKUP_ROOT_DIR/storage" -name "*.tar.gz" 2>/dev/null | wc -l)
            storage_size=$(get_size "$BACKUP_ROOT_DIR/storage")
        fi
        
        if [ -d "$BACKUP_ROOT_DIR" ]; then
            total_size=$(get_size "$BACKUP_ROOT_DIR")
        fi
        
        local mode_text="cleanup completed"
        if [ "$DRY_RUN" = true ]; then
            mode_text="cleanup analysis completed (DRY RUN)"
        fi
        
        send_notification "Timebank Backup Cleanup Completed" \
            "Backup $mode_text successfully.

Cleanup Details:
- Type: $cleanup_type cleanup
- Duration: $execution_time_formatted
- Initial disk usage: ${disk_usage}%
- Final disk usage: ${final_disk_usage}%

Current Backup Status:
- Database backups: $db_count files ($db_size)
- Storage backups: $storage_count files ($storage_size)  
- Total backup size: $total_size

Location: $BACKUP_ROOT_DIR
Completed: $(date)

For detailed logs, check: $LOG_FILE"
    fi
    
    if [ "$DRY_RUN" = true ]; then
        log "SUCCESS" "Backup cleanup analysis completed in $execution_time_formatted"
    else
        log "SUCCESS" "Backup cleanup completed in $execution_time_formatted"
    fi
    
    log "INFO" "============================================"
    log "INFO" "Cleanup process finished"
    log "INFO" "============================================"
}

# Run main function
main