<?php
define('access', 'api');
define('NEXORA_CRON_REALM_RUNNER', true);

try {
    if(!@include_once(rtrim(str_replace('\\','/', dirname(__DIR__)), '/') . '/includes/webengine.php')) throw new Exception('Could not load WebEngine CMS.');
    if(config('cron_api',true) == false) throw new Exception('Cron api disabled.');
    if(($_SERVER['REQUEST_METHOD'] ?? 'GET') !== 'POST') {
        http_response_code(405);
        header('Allow: POST');
        throw new Exception('Cron API only accepts POST.');
    }

    $secret = NexoraSecurity::requireStrongSecret('NEXORA_CRON_API_KEY', 'cron_api_key');
    $authorization = isset($_SERVER['HTTP_AUTHORIZATION']) ? trim((string)$_SERVER['HTTP_AUTHORIZATION']) : '';
    $provided = '';
    if(stripos($authorization, 'Bearer ') === 0) $provided = trim(substr($authorization, 7));
    if($provided === '' && isset($_SERVER['HTTP_X_NEXORA_CRON_KEY'])) $provided = trim((string)$_SERVER['HTTP_X_NEXORA_CRON_KEY']);
    if($provided === '' || !hash_equals($secret, $provided)) {
        http_response_code(401);
        throw new Exception('Unauthorized.');
    }

    if(!isset($_POST['realm'])) throw new Exception('Realm is required.');
    $cronRealm = NexoraRealm::selectPublic($_POST['realm'], false);
    $cronManager = new CronManager();
    $executedCrons = array();
    $cronList = $cronManager->getCronList();
    if(!is_array($cronList)) throw new Exception('There are no crons.');

    function loadCronFile($path) { include($path); }

    $requestedId = isset($_POST['id']) && $_POST['id'] !== '' ? (int)$_POST['id'] : null;
    if($requestedId === null) {
        foreach($cronList as $cron) {
            if($cron['cron_status'] != 1) continue;
            if(!nexoraCronIsDue($cron, $cronRealm)) continue;
            $filePath = __PATH_CRON__.basename($cron['cron_file_run']);
            if(is_file($filePath)) { loadCronFile($filePath); $executedCrons[] = basename($cron['cron_file_run']); }
        }
    } else {
        $singleCronExecuted = false;
        foreach($cronList as $cron) {
            if((int)$cron['cron_id'] !== $requestedId) continue;
            $filePath = __PATH_CRON__.basename($cron['cron_file_run']);
            if(is_file($filePath)) {
                loadCronFile($filePath);
                $executedCrons[] = basename($cron['cron_file_run']);
                $singleCronExecuted = true;
            }
        }
        if(!$singleCronExecuted) throw new Exception('The provided cron id is not valid.');
    }

    NexoraAudit::log('system.cron_api_run', 'realm', $cronRealm, null, array('executed'=>$executedCrons), $cronRealm);
    http_response_code(200);
    header('Content-Type: application/json');
    echo json_encode(array('code'=>200,'message'=>'Crons successfully executed.','realm'=>$cronRealm,'executed'=>$executedCrons), JSON_PRETTY_PRINT);
} catch(Exception $ex) {
    if(http_response_code() < 400) http_response_code(500);
    header('Content-Type: application/json');
    echo json_encode(array('code'=>http_response_code(),'error'=>$ex->getMessage()), JSON_PRETTY_PRINT);
}
