<?php
// ==========================================
// INDEPENDENT CRON SCRIPT
// ==========================================
// This script runs infinitely in the background and hits your target URL every minute.
// You only need to open this file in your browser ONCE to start the cron.

// Ignore user aborts and remove time limits so the script runs forever
ignore_user_abort(true);
set_time_limit(0);

$target_url = "https://mizan.yaarwin72.baby/niyamitakelasa.php";
$enable_logging = true;
$log_file = __DIR__ . '/cron_log.txt';
$lock_file = __DIR__ . '/cron.lock';

// ==========================================
// BACKGROUND PROCESS SPAWNER
// ==========================================
// If accessed via a browser, we spawn a background CLI process and exit.
// This prevents the server from killing the script when you close the tab.
if (php_sapi_name() !== 'cli' && !isset($_GET['cli_mode'])) {
    
    // Attempt to spawn using exec
    $script_path = __FILE__;
    
    if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
        pclose(popen("start /B php \"$script_path\" cli_mode", "r"));
    } else {
        exec("php \"$script_path\" cli_mode > /dev/null 2>&1 &");
    }

    echo "<h1>Independent Cron Started in CLI Background!</h1>";
    echo "<p>The cron is now safely detached from the browser. It will hit <b>$target_url</b> exactly on the minute.</p>";
    echo "<p>You can completely close this page/browser, and it will keep running!</p>";
    exit;
}

// If we reach here, we are running in the background CLI!

// Check if it's already running to prevent multiple loops
if (file_exists($lock_file)) {
    $last_run = filemtime($lock_file);
    // If lock file is younger than 3 minutes, assume it's still running
    if (time() - $last_run < 180) {
        die("Cron is already running in the background. (Lock file active)\n");
    }
}

// Update lock file to indicate it started
file_put_contents($lock_file, "Running started at: " . date('Y-m-d H:i:s'));

// Set this to 1, 2, or 3 if your server has a network delay.
// Example: If it hits 3 seconds late, set $advance_seconds = 3; so it triggers at 57 seconds.
$advance_seconds = 0;

// Infinite loop to hit the URL
while (true) {
    // Touch lock file to indicate we are still alive
    touch($lock_file);

    $current_second = (int)date('s');
    
    // Calculate target second based on advance time
    $target_second = 60 - $advance_seconds;
    if ($target_second == 60) $target_second = 0;

    // Calculate how many seconds left until 2 seconds BEFORE our target
    // We will sleep most of the time, then use a tight loop for perfect precision
    $sleep_time = 60 - $current_second - $advance_seconds;
    
    if ($sleep_time < 0) {
        $sleep_time += 60; 
    }

    // Sleep until 2 seconds before the target hit time
    if ($sleep_time > 2) {
        sleep($sleep_time - 2);
    }

    // Tight precision loop: Check time every 10 milliseconds until it exactly hits the target
    while (true) {
        $sec = (int)date('s');
        if ($sec === $target_second) {
            break; // EXACT MATCH! Fire immediately
        }
        usleep(10000); // 10 ms delay for ultra-precision
    }

    // Now it's the exact target second! Call the URL
    $ch = curl_init($target_url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_TIMEOUT, 30);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    // Force IPv4 to prevent slow DNS lookups (common cause of 2-3 sec delay)
    curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); 
    
    // Fire the request
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    curl_close($ch);

    // Log the action
    if ($enable_logging) {
        // Log the exact precise time with milliseconds
        list($usec, $sec) = explode(" ", microtime());
        $ms = sprintf("%03d", round($usec * 1000));
        $time = date('Y-m-d H:i:s', $sec) . ".$ms";
        
        $log_msg = "[$time] Pinged $target_url | HTTP Status: $http_code\n";
        file_put_contents($log_file, $log_msg, FILE_APPEND);
    }
    
    // Sleep for a few seconds so we don't accidentally fire twice in the same target second
    sleep(5);
}
?>
