#!/usr/bin/env php
<?php
/**
 * Backup Scheduler - Processes scheduled backups
 * This script should be run via cron every 5 minutes
 */

// Determine the correct base directory
// In production: /docker/whp/web (synced from /root/whp/web-files)
// In development: /home/jknapp/code/whp/web-files
if (file_exists('/docker/whp/web/configs/config.php')) {
    // Production environment - web files are synced to /docker/whp/web/
    $webDir = '/docker/whp/web';
} else {
    // Development/testing environment - web files are in repo
    $webDir = dirname(__DIR__) . '/web-files';
}

// Validate web directory exists and contains required files
if (!is_dir($webDir)) {
    die("Error: Web directory not found: $webDir\n");
}

// Set error reporting
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Validate and include necessary files
$requiredFiles = [
    'configs/config.php',
    'libs/mysqlmgmt.php',
    'libs/BackupSchedule.php',
    'libs/BackupEngine.php',
    'libs/BackupHistory.php'
];

foreach ($requiredFiles as $file) {
    $fullPath = $webDir . '/' . $file;

    // Security validation
    $realPath = realpath($fullPath);
    if ($realPath === false) {
        die("Error: Required file not found: $fullPath\n");
    }

    // Check for symlinks (security)
    if (is_link($fullPath)) {
        die("Security error: Symlink detected: $fullPath\n");
    }

    // Verify real path is within expected directory
    $expectedPrefix = realpath($webDir);
    if (strpos($realPath, $expectedPrefix . '/') !== 0) {
        die("Security error: File outside expected directory: $fullPath\n");
    }

    require_once($realPath);
}

use WHPBackup\BackupSchedule;
use WHPBackup\BackupEngine;
use WHPBackup\BackupHistory;

echo "Starting backup scheduler at " . date('Y-m-d H:i:s') . "\n";

try {
    // Get due schedules
    $schedules = BackupSchedule::getDueSchedules();
    
    if (empty($schedules)) {
        echo "No schedules due for processing.\n";
        exit(0);
    }
    
    echo "Found " . count($schedules) . " schedules due for processing.\n";
    
    $engine = new BackupEngine();
    
    foreach ($schedules as $scheduleData) {
        echo "Processing schedule ID: " . $scheduleData['id'] . "\n";
        
        try {
            $schedule = new BackupSchedule(null, $scheduleData['id']);
            
            // Create backup based on type
            $backupCount = 0;
            $failedCount = 0;
            switch ($scheduleData['backup_type']) {
                case 'site':
                    if ($scheduleData['resource_name']) {
                        echo "  Creating backup for site: {$scheduleData['resource_name']}\n";
                        try {
                            $result = $engine->createSiteBackup($scheduleData['user'], $scheduleData['resource_name'], $scheduleData['target_id']);
                            if ($result['success']) {
                                $backupCount = 1;
                                echo "    Successfully queued backup for site: {$scheduleData['resource_name']}\n";
                            } else {
                                $failedCount = 1;
                                echo "    Failed to queue backup for site: {$scheduleData['resource_name']} - {$result['error']}\n";
                            }
                        } catch (Exception $e) {
                            $failedCount = 1;
                            echo "    Exception creating backup for site: {$scheduleData['resource_name']} - " . $e->getMessage() . "\n";
                        }
                    } else {
                        // Backup all sites for user
                        $sites = $engine->getUserSites($scheduleData['user']);
                        echo "  Found " . count($sites) . " sites for user {$scheduleData['user']}\n";
                        foreach ($sites as $site) {
                            echo "  Creating backup for site: $site\n";
                            try {
                                $result = $engine->createSiteBackup($scheduleData['user'], $site, $scheduleData['target_id']);
                                if ($result['success']) {
                                    $backupCount++;
                                    echo "    Successfully queued backup for site: $site\n";
                                } else {
                                    $failedCount++;
                                    echo "    Failed to queue backup for site: $site - {$result['error']}\n";
                                }
                            } catch (Exception $e) {
                                $failedCount++;
                                echo "    Exception creating backup for site: $site - " . $e->getMessage() . "\n";
                            }
                        }
                    }
                    break;
                    
                case 'userfiles':
                    echo "  Creating userfiles backup for user: {$scheduleData['user']}\n";
                    try {
                        $result = $engine->createUserfilesBackup($scheduleData['user'], $scheduleData['target_id']);
                        if ($result['success']) {
                            $backupCount = 1;
                            echo "    Successfully queued userfiles backup\n";
                        } else {
                            $failedCount = 1;
                            echo "    Failed to queue userfiles backup - {$result['error']}\n";
                        }
                    } catch (Exception $e) {
                        $failedCount = 1;
                        echo "    Exception creating userfiles backup - " . $e->getMessage() . "\n";
                    }
                    break;
                    
                case 'database':
                    if ($scheduleData['resource_name']) {
                        echo "  Creating backup for database: {$scheduleData['resource_name']}\n";
                        try {
                            $result = $engine->createDatabaseBackup($scheduleData['user'], $scheduleData['resource_name'], $scheduleData['target_id']);
                            if ($result['success']) {
                                $backupCount = 1;
                                echo "    Successfully queued backup for database: {$scheduleData['resource_name']}\n";
                            } else {
                                $failedCount = 1;
                                echo "    Failed to queue backup for database: {$scheduleData['resource_name']} - {$result['error']}\n";
                            }
                        } catch (Exception $e) {
                            $failedCount = 1;
                            echo "    Exception creating backup for database: {$scheduleData['resource_name']} - " . $e->getMessage() . "\n";
                        }
                    } else {
                        // Backup all databases for user
                        $databases = $engine->getUserDatabases($scheduleData['user']);
                        echo "  Found " . count($databases) . " databases for user {$scheduleData['user']}\n";
                        foreach ($databases as $database) {
                            echo "  Creating backup for database: $database\n";
                            try {
                                $result = $engine->createDatabaseBackup($scheduleData['user'], $database, $scheduleData['target_id']);
                                if ($result['success']) {
                                    $backupCount++;
                                    echo "    Successfully queued backup for database: $database\n";
                                } else {
                                    $failedCount++;
                                    echo "    Failed to queue backup for database: $database - {$result['error']}\n";
                                }
                            } catch (Exception $e) {
                                $failedCount++;
                                echo "    Exception creating backup for database: $database - " . $e->getMessage() . "\n";
                            }
                        }
                    }
                    break;

                case 'postgres_database':
                    if ($scheduleData['resource_name']) {
                        echo "  Creating PG backup for database: {$scheduleData['resource_name']}\n";
                        try {
                            $result = $engine->createPostgresDatabaseBackup($scheduleData['user'], $scheduleData['resource_name'], $scheduleData['target_id']);
                            if ($result['success']) {
                                $backupCount = 1;
                                echo "    Successfully queued PG backup for database: {$scheduleData['resource_name']}\n";
                            } else {
                                $failedCount = 1;
                                echo "    Failed to queue PG backup for database: {$scheduleData['resource_name']} - {$result['error']}\n";
                            }
                        } catch (Exception $e) {
                            $failedCount = 1;
                            echo "    Exception creating PG backup for database: {$scheduleData['resource_name']} - " . $e->getMessage() . "\n";
                        }
                    } else {
                        // Backup all PostgreSQL databases for user
                        $pgDatabases = $engine->getUserPostgresDatabases($scheduleData['user']);
                        echo "  Found " . count($pgDatabases) . " PG databases for user {$scheduleData['user']}\n";
                        foreach ($pgDatabases as $database) {
                            echo "  Creating PG backup for database: $database\n";
                            try {
                                $result = $engine->createPostgresDatabaseBackup($scheduleData['user'], $database, $scheduleData['target_id']);
                                if ($result['success']) {
                                    $backupCount++;
                                    echo "    Successfully queued PG backup for database: $database\n";
                                } else {
                                    $failedCount++;
                                    echo "    Failed to queue PG backup for database: $database - {$result['error']}\n";
                                }
                            } catch (Exception $e) {
                                $failedCount++;
                                echo "    Exception creating PG backup for database: $database - " . $e->getMessage() . "\n";
                            }
                        }
                    }
                    break;

                default:
                    throw new Exception("Unknown backup type: " . $scheduleData['backup_type']);
            }
            
            // Only update last run time if at least one backup was successfully queued
            if ($backupCount > 0) {
                $schedule->updateLastRun();
                echo "  Updated schedule last run time\n";
            } else if ($failedCount > 0) {
                echo "  WARNING: No backups were successfully queued, not updating last run time\n";
                // Still mark as run to avoid running again immediately, but log the failure
                error_log("Schedule ID {$scheduleData['id']} failed to queue any backups for user {$scheduleData['user']}");
                $schedule->updateLastRun();
            }

            // Clean up old backups based on retention (only if we successfully created new ones)
            if ($backupCount > 0) {
                try {
                    echo "  Cleaning up old backups based on retention settings...\n";
                    $engine->cleanupScheduledBackups($scheduleData['target_id'], $scheduleData['user'], $scheduleData['backup_type'], $scheduleData['max_retention']);
                    echo "  Cleanup completed\n";
                } catch (Exception $e) {
                    echo "  WARNING: Failed to clean up old backups: " . $e->getMessage() . "\n";
                }
            }

            $summary = "Successfully processed schedule ID: " . $scheduleData['id'] . " (";
            if ($backupCount > 0) {
                $summary .= "created $backupCount backup" . ($backupCount > 1 ? 's' : '');
            }
            if ($failedCount > 0) {
                if ($backupCount > 0) $summary .= ", ";
                $summary .= "failed $failedCount backup" . ($failedCount > 1 ? 's' : '');
            }
            $summary .= ")\n";
            echo $summary;
            
        } catch (Exception $e) {
            echo "Error processing schedule ID " . $scheduleData['id'] . ": " . $e->getMessage() . "\n";
        }
    }
    
} catch (Exception $e) {
    echo "Fatal error: " . $e->getMessage() . "\n";
    exit(1);
}

echo "Backup scheduler completed at " . date('Y-m-d H:i:s') . "\n";