<?php
/**
 * Backup a Wasabi S3 v2.0 - Ejecucion por Cron
 * ================================================
 * Ejecutar desde crontab. Realiza backup de todos los wikis a nicc-sistema.
 * Usa la funcion backupWiki() de functions.php (upload completo + cleanup).
 *
 * Cron diario 3:00 AM:
 *   0 3 * * * /usr/local/bin/php /home/systeng3/public_html/_siedeployer_patch/patches/backup_wasabi/backup_cron.php >> /dev/null 2>&1
 *
 * Cron semanal domingos 2:00 AM:
 *   0 2 * * 0 /usr/local/bin/php /home/systeng3/public_html/_siedeployer_patch/patches/backup_wasabi/backup_cron.php >> /dev/null 2>&1
 *
 * Logs en: patches/backup_wasabi/logs/
 */

if (php_sapi_name() !== 'cli') {
    die("Solo ejecucion por linea de comandos.\n");
}

require_once __DIR__ . '/functions.php';

set_time_limit(0);
ini_set('memory_limit', MEMORY_LIMIT);

// ============================================================
// LOCK (evitar ejecucion concurrente, con timeout automatico)
// ============================================================

$lockFp = acquireLockWithTimeout();
if (!$lockFp) {
    echo "ERROR: Otro proceso de backup esta en ejecucion. Saliendo.\n";
    exit(1);
}

// Limpiar logs antiguos
cleanOldLogs(30);

// ============================================================
// LOGGING
// ============================================================

if (!is_dir(LOG_DIR)) @mkdir(LOG_DIR, 0755, true);
$logFile = LOG_DIR . '/cron_' . date('Y-m-d') . '.log';

function cronLog($msg) {
    global $logFile;
    $line = date('Y-m-d H:i:s') . ' ' . $msg;
    echo $line . "\n";
    @file_put_contents($logFile, $line . "\n", FILE_APPEND | LOCK_EX);
}

// ============================================================
// EJECUCION PRINCIPAL
// ============================================================

cronLog("========================================");
cronLog("BACKUP CRON INICIO (v2.0)");
cronLog("Bucket: " . WASABI_BUCKET);
cronLog("========================================");

$items = @scandir(SEARCH_PATH);
if (!$items) {
    cronLog("ERROR: No se puede leer " . SEARCH_PATH);
    releaseLock($lockFp);
    exit(1);
}

$wikis = [];
foreach ($items as $item) {
    if (empty($item) || $item[0] === '.' || $item[0] === '_') continue;
    if (!isValidWikiName($item)) continue;
    $full = SEARCH_PATH . '/' . $item;
    if (is_dir($full) && isDokuWiki($full)) $wikis[] = $item;
}
sort($wikis);

cronLog("Wikis encontrados: " . count($wikis));

$totalFiles   = 0;
$totalDeleted = 0;
$totalErrors  = 0;
$startTime    = microtime(true);

foreach ($wikis as $i => $wikiName) {
    $wikiPath = SEARCH_PATH . '/' . $wikiName;
    $n = ($i + 1) . '/' . count($wikis);

    cronLog("[{$n}] {$wikiName} - iniciando...");

    // Renovar lock para que no expire durante wikis grandes
    touchLock();

    $result = backupWiki($wikiName, $wikiPath);

    $totalFiles   += $result['uploaded'];
    $totalDeleted += $result['deleted'];
    $totalErrors  += $result['errors'];

    $status = $result['ok'] ? 'OK' : 'ERRORES';
    $skippedMsg = isset($result['skipped']) ? ", {$result['skipped']} sin cambios" : '';
    cronLog("[{$n}] {$wikiName} - {$status}: {$result['uploaded']} subidos{$skippedMsg}, {$result['deleted']} borrados, {$result['errors']} errores");

    // Guardar manifest si fue exitoso (para skip rapido en proxima ejecucion)
    if ($result['ok']) {
        saveManifest($wikiName);
    }
}

$elapsed = round(microtime(true) - $startTime, 1);

cronLog("========================================");
cronLog("BACKUP CRON FINALIZADO");
cronLog("Wikis: " . count($wikis));
cronLog("Archivos subidos: {$totalFiles}");
cronLog("Archivos borrados: {$totalDeleted}");
cronLog("Errores: {$totalErrors}");
cronLog("Tiempo: {$elapsed}s");
cronLog("========================================");

// Guardar estado para la UI
$progress = [
    'last_run'       => date('Y-m-d H:i:s'),
    'wikis'          => count($wikis),
    'files_uploaded' => $totalFiles,
    'files_deleted'  => $totalDeleted,
    'errors'         => $totalErrors,
    'elapsed'        => $elapsed,
    'mode'           => 'cron',
];
file_put_contents(PROGRESS_FILE, json_encode($progress, JSON_PRETTY_PRINT), LOCK_EX);

releaseLock($lockFp);
exit($totalErrors > 0 ? 1 : 0);
