#!/bin/bash

# Laravel Timebank Backup Setup Script
# Initializes the backup system and performs initial configuration
# Usage: ./setup-backups.sh

set -e

# Configuration
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"

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

# Function to print colored output
print_status() {
    local level="$1"
    local message="$2"
    
    case "$level" in
        "INFO")
            echo -e "${BLUE}[INFO]${NC} $message"
            ;;
        "SUCCESS")
            echo -e "${GREEN}[SUCCESS]${NC} $message"
            ;;
        "WARNING")
            echo -e "${YELLOW}[WARNING]${NC} $message"
            ;;
        "ERROR")
            echo -e "${RED}[ERROR]${NC} $message"
            ;;
    esac
}

# Function to check prerequisites
check_prerequisites() {
    print_status "INFO" "Checking prerequisites..."
    
    local missing_tools=()
    
    # Check required commands
    local required_commands=("mysqldump" "mysql" "rsync" "tar" "gzip" "find" "awk")
    
    for cmd in "${required_commands[@]}"; do
        if ! command -v "$cmd" >/dev/null 2>&1; then
            missing_tools+=("$cmd")
        fi
    done
    
    if [ ${#missing_tools[@]} -gt 0 ]; then
        print_status "ERROR" "Missing required tools: ${missing_tools[*]}"
        print_status "INFO" "Please install missing tools and try again"
        return 1
    fi
    
    print_status "SUCCESS" "All required tools are available"
    return 0
}

# Function to verify environment configuration
check_environment() {
    print_status "INFO" "Checking environment configuration..."
    
    if [ ! -f "$PROJECT_ROOT/.env" ]; then
        print_status "ERROR" ".env file not found in $PROJECT_ROOT"
        return 1
    fi
    
    # Load environment loader
    source "$SCRIPT_DIR/load-env.sh"
    
    # Load environment variables
    if ! load_env "$PROJECT_ROOT/.env"; then
        return 1
    fi
    
    # Check required database variables
    local missing_vars=()
    
    if [ -z "$DB_DATABASE" ]; then missing_vars+=("DB_DATABASE"); fi
    if [ -z "$DB_USERNAME" ]; then missing_vars+=("DB_USERNAME"); fi
    if [ -z "$DB_HOST" ]; then missing_vars+=("DB_HOST"); fi
    
    if [ ${#missing_vars[@]} -gt 0 ]; then
        print_status "ERROR" "Missing required environment variables: ${missing_vars[*]}"
        return 1
    fi
    
    print_status "SUCCESS" "Environment configuration is valid"
    return 0
}

# Function to test database connection
test_database_connection() {
    print_status "INFO" "Testing database connection..."
    
    # Create MySQL configuration file for secure password handling
    local mysql_cnf_file="/tmp/mysql_test_$$.cnf"
    cat > "$mysql_cnf_file" <<EOF
[mysql]
host=${DB_HOST:-127.0.0.1}
port=${DB_PORT:-3306}
user=$DB_USERNAME
password=$DB_PASSWORD
EOF
    
    # Set secure permissions on the config file
    chmod 600 "$mysql_cnf_file"
    
    if mysql --defaults-extra-file="$mysql_cnf_file" -e "SELECT 1;" >/dev/null 2>&1; then
        print_status "SUCCESS" "Database connection successful"
        rm -f "$mysql_cnf_file"
        return 0
    else
        print_status "ERROR" "Database connection failed"
        rm -f "$mysql_cnf_file"
        return 1
    fi
}

# Function to set up backup directories
setup_directories() {
    print_status "INFO" "Setting up backup directories..."
    
    local backup_dirs=(
        "$PROJECT_ROOT/backups"
        "$PROJECT_ROOT/backups/database/daily"
        "$PROJECT_ROOT/backups/database/weekly"
        "$PROJECT_ROOT/backups/database/monthly"
        "$PROJECT_ROOT/backups/database/pre-restore"
        "$PROJECT_ROOT/backups/storage/daily"
        "$PROJECT_ROOT/backups/storage/weekly"
        "$PROJECT_ROOT/backups/storage/monthly"
        "$PROJECT_ROOT/backups/storage/snapshots"
        "$PROJECT_ROOT/backups/storage/pre-restore"
        "$PROJECT_ROOT/backups/logs"
    )
    
    for dir in "${backup_dirs[@]}"; do
        if [ ! -d "$dir" ]; then
            mkdir -p "$dir"
            print_status "INFO" "Created directory: $dir"
        fi
    done
    
    # Set appropriate permissions
    chmod 755 "$PROJECT_ROOT/backups"
    chmod -R 750 "$PROJECT_ROOT/backups"/{database,storage}
    chmod 755 "$PROJECT_ROOT/backups/logs"
    
    print_status "SUCCESS" "Backup directories created successfully"
}

# Function to make scripts executable
setup_script_permissions() {
    print_status "INFO" "Setting up script permissions..."
    
    local scripts=(
        "$SCRIPT_DIR/backup-database.sh"
        "$SCRIPT_DIR/backup-storage.sh"
        "$SCRIPT_DIR/backup-all.sh"
        "$SCRIPT_DIR/restore-database.sh"
        "$SCRIPT_DIR/restore-storage.sh"
        "$SCRIPT_DIR/cleanup-backups.sh"
    )
    
    for script in "${scripts[@]}"; do
        if [ -f "$script" ]; then
            chmod +x "$script"
            print_status "INFO" "Made executable: $(basename "$script")"
        else
            print_status "WARNING" "Script not found: $(basename "$script")"
        fi
    done
    
    print_status "SUCCESS" "Script permissions configured"
}

# Function to run initial test backup
run_test_backup() {
    print_status "INFO" "Running initial test backup..."
    
    # Test database backup
    if [ -x "$SCRIPT_DIR/backup-database.sh" ]; then
        print_status "INFO" "Testing database backup..."
        if "$SCRIPT_DIR/backup-database.sh" daily; then
            print_status "SUCCESS" "Database backup test successful"
        else
            print_status "ERROR" "Database backup test failed"
            return 1
        fi
    fi
    
    # Test storage backup
    if [ -x "$SCRIPT_DIR/backup-storage.sh" ]; then
        print_status "INFO" "Testing storage backup..."
        if "$SCRIPT_DIR/backup-storage.sh" daily; then
            print_status "SUCCESS" "Storage backup test successful"
        else
            print_status "ERROR" "Storage backup test failed"
            return 1
        fi
    fi
    
    return 0
}

# Function to show next steps
show_next_steps() {
    print_status "SUCCESS" "Backup system setup completed successfully!"
    echo ""
    print_status "INFO" "Next steps:"
    echo "  1. Review the backup configuration in BACKUP_GUIDE.md"
    echo "  2. Set up automated backups using cron:"
    echo "     sudo cp scripts/cron-backup.conf /etc/cron.d/timebank-backup"
    echo "     sudo nano /etc/cron.d/timebank-backup  # Edit paths and email"
    echo "  3. Test the complete backup system:"
    echo "     ./scripts/backup-all.sh daily --verify"
    echo "  4. Test restore procedures:"
    echo "     ./scripts/restore-database.sh --list-backups"
    echo "  5. Set up monitoring and notifications"
    echo ""
    print_status "INFO" "Available commands:"
    echo "  ./scripts/backup-all.sh daily          # Daily backup"
    echo "  ./scripts/backup-all.sh weekly         # Weekly backup"
    echo "  ./scripts/backup-all.sh monthly        # Monthly backup"
    echo "  ./scripts/restore-database.sh --latest # Restore database"
    echo "  ./scripts/restore-storage.sh --latest  # Restore storage"
    echo "  ./scripts/cleanup-backups.sh --dry-run # Check cleanup"
    echo ""
}

# Function to display backup status
show_backup_status() {
    print_status "INFO" "Current backup status:"
    
    local backup_dir="$PROJECT_ROOT/backups"
    
    if [ -d "$backup_dir" ]; then
        # Count backups
        local db_backups=$(find "$backup_dir/database" -name "*.sql.gz" 2>/dev/null | wc -l)
        local storage_backups=$(find "$backup_dir/storage" -name "*.tar.gz" 2>/dev/null | wc -l)
        
        echo "  Database backups: $db_backups"
        echo "  Storage backups: $storage_backups"
        
        if [ -d "$backup_dir" ]; then
            local total_size=$(du -sh "$backup_dir" 2>/dev/null | cut -f1)
            echo "  Total backup size: $total_size"
        fi
        
        # Show recent backups
        local recent_db=$(find "$backup_dir/database" -name "*.sql.gz" -mtime -1 2>/dev/null | head -n 1)
        local recent_storage=$(find "$backup_dir/storage" -name "*.tar.gz" -mtime -1 2>/dev/null | head -n 1)
        
        if [ -n "$recent_db" ]; then
            echo "  Latest database backup: $(basename "$recent_db") ($(date -r "$recent_db" '+%Y-%m-%d %H:%M:%S'))"
        fi
        
        if [ -n "$recent_storage" ]; then
            echo "  Latest storage backup: $(basename "$recent_storage") ($(date -r "$recent_storage" '+%Y-%m-%d %H:%M:%S'))"
        fi
    else
        echo "  No backups found"
    fi
    
    echo ""
}

# Main execution
main() {
    echo "============================================"
    echo "  Laravel Timebank Backup System Setup    "
    echo "============================================"
    echo ""
    
    # Check if already set up
    if [ -d "$PROJECT_ROOT/backups" ] && [ -f "$PROJECT_ROOT/backups/backup.log" ]; then
        print_status "INFO" "Backup system appears to already be configured"
        show_backup_status
        
        read -p "Do you want to re-run the setup? [y/N]: " -n 1 -r
        echo ""
        if [[ ! $REPLY =~ ^[Yy]$ ]]; then
            print_status "INFO" "Setup cancelled"
            exit 0
        fi
        echo ""
    fi
    
    # Run setup steps
    if ! check_prerequisites; then
        exit 1
    fi
    
    if ! check_environment; then
        print_status "INFO" "Please configure your .env file with proper database credentials"
        exit 1
    fi
    
    if ! test_database_connection; then
        print_status "INFO" "Please check your database configuration and connection"
        exit 1
    fi
    
    setup_directories
    setup_script_permissions
    
    # Ask if user wants to run test backup
    echo ""
    read -p "Do you want to run an initial test backup? [Y/n]: " -n 1 -r
    echo ""
    if [[ ! $REPLY =~ ^[Nn]$ ]]; then
        if run_test_backup; then
            print_status "SUCCESS" "Test backup completed successfully"
        else
            print_status "WARNING" "Test backup had issues, but setup is complete"
        fi
    fi
    
    echo ""
    show_next_steps
}

# Check if running from correct directory
if [ ! -f "$PROJECT_ROOT/composer.json" ] || [ ! -f "$PROJECT_ROOT/.env.example" ]; then
    print_status "ERROR" "This script must be run from the Laravel project root directory"
    exit 1
fi

# Run main function
main