#!/usr/bin/env php
<?php
/**
 * Backup Cleanup Script
 * This script cleans up old backups based on retention policies
 * Run via cron: daily at 2 AM - add to crontab: 0 2 * * * /usr/bin/php /path/to/cleanup-backups.php
 */

// Set up path to include WHP libraries
$whpPath = realpath(__DIR__ . '/../web-files');
if (!$whpPath) {
    die("Error: Could not find WHP web files directory\n");
}

// Add WHP lib path
ini_set('include_path', $whpPath . '/libs' . PATH_SEPARATOR . ini_get('include_path'));

// Load configuration (only if not already loaded)
if (!defined('MYSQL_PASS')) {
    require_once $whpPath . '/configs/config.php';
}

// Load backup system
require_once $whpPath . '/libs/BackupEngine.php';
require_once $whpPath . '/libs/BackupTarget.php';
require_once $whpPath . '/libs/BackupHistory.php';

use WHPBackup\BackupEngine;
use WHPBackup\BackupTarget;
use WHPBackup\BackupHistory;

// Enable error reporting for CLI
error_reporting(E_ALL);
ini_set('display_errors', 1);

// Function to log messages
function logMessage($message, $level = 'INFO') {
    $timestamp = date('Y-m-d H:i:s');
    $logMessage = "[$timestamp] [$level] $message\n";
    $logFile = '/var/log/whp-backup-cleanup.log';
    
    // Write to log file
    file_put_contents($logFile, $logMessage, FILE_APPEND | LOCK_EX);
    
    // Only output to stdout if running interactively (not from cron)
    if (php_sapi_name() === 'cli' && function_exists('posix_isatty') && posix_isatty(STDOUT)) {
        echo $logMessage;
    }
}

// Function to format bytes
function formatBytes($bytes, $precision = 2) {
    $units = array('B', 'KB', 'MB', 'GB', 'TB');
    
    for ($i = 0; $bytes > 1024 && $i < count($units) - 1; $i++) {
        $bytes /= 1024;
    }
    
    return round($bytes, $precision) . ' ' . $units[$i];
}

try {
    logMessage("Starting backup cleanup process");
    
    $engine = new BackupEngine();
    $totalDeleted = 0;
    $totalSizeFreed = 0;
    
    // Get all backup targets
    $targets = BackupTarget::listTargets();
    
    if (empty($targets)) {
        logMessage("No backup targets found");
        exit(0);
    }
    
    foreach ($targets as $targetData) {
        $target = new BackupTarget(null, $targetData['id']);
        $targetName = $targetData['name'];
        
        logMessage("Processing target: $targetName");
        
        $retentionDays = $targetData['retention_days'];
        $maxBackups = $targetData['max_backups'];
        
        // Clean up old backups based on retention days
        if ($retentionDays > 0) {
            logMessage("Cleaning up backups older than $retentionDays days for target: $targetName");
            
            $oldBackups = BackupHistory::getOldBackups(null, $targetData['id'], $retentionDays);
            
            foreach ($oldBackups as $backup) {
                try {
                    $size = $backup['backup_size'];
                    $name = $backup['backup_name'];
                    
                    $engine->deleteBackup($backup['id'], $backup['user']);
                    
                    $totalDeleted++;
                    $totalSizeFreed += $size;
                    
                    logMessage("Deleted old backup: $name (" . formatBytes($size) . ")");
                    
                } catch (Exception $e) {
                    logMessage("Failed to delete backup {$backup['id']}: " . $e->getMessage(), 'ERROR');
                }
            }
        }
        
        // Clean up excess backups based on max count
        if ($maxBackups > 0) {
            logMessage("Cleaning up excess backups (max: $maxBackups) for target: $targetName");
            
            // Get all users who have backups for this target
            $users = [];
            $backups = BackupHistory::listBackups(null, ['target_id' => $targetData['id'], 'exclude_deleted' => true]);
            
            foreach ($backups as $backup) {
                $users[$backup['user']] = true;
            }
            
            $backupTypes = ['site', 'userfiles', 'database'];
            
            foreach (array_keys($users) as $user) {
                foreach ($backupTypes as $type) {
                    $excessBackups = BackupHistory::getExcessBackups(null, $targetData['id'], $user, $type, $maxBackups);
                    
                    foreach ($excessBackups as $backup) {
                        try {
                            $size = $backup['backup_size'];
                            $name = $backup['backup_name'];
                            
                            $engine->deleteBackup($backup['id'], $backup['user']);
                            
                            $totalDeleted++;
                            $totalSizeFreed += $size;
                            
                            logMessage("Deleted excess backup: $name (" . formatBytes($size) . ")");
                            
                        } catch (Exception $e) {
                            logMessage("Failed to delete excess backup {$backup['id']}: " . $e->getMessage(), 'ERROR');
                        }
                    }
                }
            }
        }
    }
    
    logMessage("Backup cleanup completed");
    logMessage("Total backups deleted: $totalDeleted");
    logMessage("Total space freed: " . formatBytes($totalSizeFreed));
    
} catch (Exception $e) {
    logMessage("Backup cleanup failed: " . $e->getMessage(), 'ERROR');
    exit(1);
}