<?php
// cron_runner.php - Chained checkup pipeline for environments with a
// single cron slot. Invokes (in order): uptime_monitor, health_check (json),
// log_rotate, security_audit. Writes a combined status JSON to
// backups/cron_runner_last.json.
//
// Web: cron_runner.php?token=<config.backup_sync.cron_key>
// CLI: php cron_runner.php

$isCli = (php_sapi_name() === 'cli');
require_once __DIR__ . '/helpers.php';

if (!$isCli) {
    $expected = (string) getConfig('backup_sync.cron_key', '');
    $provided = (string) ($_GET['token'] ?? '');
    if ($expected === '' || !hash_equals($expected, $provided)) {
        http_response_code(403);
        header('Content-Type: text/plain');
        die("Forbidden.");
    }
    header('Content-Type: text/plain; charset=utf-8');
}

$monitorToken = (string) getConfig('backup_sync.monitor_token', '');
$cronKey      = (string) getConfig('backup_sync.cron_key', '');

$base = 'http://127.0.0.1';
if (!$isCli) {
    $scheme = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on') ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'] ?? '127.0.0.1';
    $base = $scheme . '://' . $host;
}

$out = ['started_at' => date('c'), 'steps' => []];

$call = function (string $name, string $url) use (&$out): void {
    $start = microtime(true);
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 120);
    curl_setopt($ch, CURLOPT_USERAGENT, 'Fon2FixCronRunner/1.0');
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
    $body  = curl_exec($ch);
    $code  = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err   = curl_error($ch);
    curl_close($ch);
    $out['steps'][$name] = [
        'http_code' => $code,
        'ms'        => (int) ((microtime(true) - $start) * 1000),
        'error'     => $err ?: null,
    ];
    echo sprintf("[%s] %s -> HTTP %d (%dms)\n", date('H:i:s'), $name, $code, $out['steps'][$name]['ms']);
};

// 1) Uptime monitor
if ($monitorToken !== '') {
    $call('uptime', $base . '/uptime_monitor.php?access_token=' . rawurlencode($monitorToken));
} else {
    $out['steps']['uptime'] = ['skipped' => 'monitor_token not set'];
}

// 2) Health check (JSON)
if ($cronKey !== '') {
    $call('health', $base . '/health_check.php?cron=1&token=' . rawurlencode($cronKey) . '&format=json');
} else {
    $out['steps']['health'] = ['skipped' => 'cron_key not set'];
}

// 3) Log rotate
if ($cronKey !== '') {
    $call('log_rotate', $base . '/log_rotate.php?token=' . rawurlencode($cronKey));
} else {
    $out['steps']['log_rotate'] = ['skipped' => 'cron_key not set'];
}

// 4) Security audit
if ($cronKey !== '') {
    $call('security_audit', $base . '/security_audit.php?cron=1&token=' . rawurlencode($cronKey));
} else {
    $out['steps']['security_audit'] = ['skipped' => 'cron_key not set'];
}

$out['finished_at'] = date('c');

$logDir = __DIR__ . '/backups';
if (is_dir($logDir) && is_writable($logDir)) {
    @file_put_contents($logDir . '/cron_runner_last.json', json_encode($out, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
}

echo "\nDONE @ " . $out['finished_at'] . "\n";
