<?php

declare(strict_types=1);

/**
 * PPPHP database cloning — run from cron on a BACKUP server.
 *
 *   # every 6 hours (crontab):
 *   #   0 [slash]6 * * * php /path/to/PpPhp/bin/pp-clone-databases.php >> storage/logs/clone.log 2>&1
 *
 * Pulls each managed database that has changed on the paired main server and
 * restores it into a local `replica_*` copy. Databases whose fingerprint is
 * unchanged are skipped before any transfer, so a quiet estate costs one small
 * HTTPS call.
 *
 * Does nothing unless this install is a BACKUP and scheduled cloning is enabled
 * in the Database Manager. `--force` runs regardless of the schedule (but still
 * refuses on a main, and still respects the run lock).
 *
 * This is cron-driven rather than request-driven on purpose: a clone can run for
 * minutes, and hanging a visitor's page load for the length of a database
 * transfer is not acceptable.
 *
 * CLI only — web-cron hosts should use the token-guarded
 * /licensing/server/clone-run URL instead.
 */

if (PHP_SAPI !== 'cli') {
    http_response_code(404);
    exit("This script runs from the command line only.\n");
}

define('BASE_PATH', dirname(__DIR__));
error_reporting(E_ALL & ~E_DEPRECATED);

// Same clock as the web console (default Asia/Kathmandu) so cron-written and
// web-read timestamps never drift apart. PP_TIMEZONE also aligns the MySQL session.
$__tz = (string) (((array) (is_file(BASE_PATH . '/config/app.php') ? require BASE_PATH . '/config/app.php' : []))['timezone'] ?? 'Asia/Kathmandu');
if ($__tz !== '') { @date_default_timezone_set($__tz); if (!defined('PP_TIMEZONE')) define('PP_TIMEZONE', $__tz); }

require_once BASE_PATH . '/core/Autoloader.php';
$autoloader = new \PpPhp\Core\Autoloader();
$autoloader->addNamespace('PpPhp\\Core\\', BASE_PATH . '/core/');
$autoloader->addNamespace('PpPhp\\Plugins\\', BASE_PATH . '/plugins/');
$autoloader->register();

require_once BASE_PATH . '/core/Helpers.php';

$dbConfig = require BASE_PATH . '/config/database.php';
$container = new \PpPhp\Core\Container();
$container->set(\PpPhp\Core\Config::class, new \PpPhp\Core\Config([
    'base_url'   => '',
    'assets_url' => '/assets',
    'db_config'  => new \PpPhp\Core\Config($dbConfig),
]));
\PpPhp\Core\DB::Init();
\PpPhp\Core\DB::SetConnection();

$force = in_array('--force', $argv, true);
$res   = (new \PpPhp\Core\Databases\CloneSchedule(BASE_PATH))->run(['force' => $force]);

$stamp = '[' . date('Y-m-d H:i:s') . '] ';
echo $stamp . ($res['message'] ?? 'done') . "\n";

// Per-database detail, so a cron log is actually diagnosable after the fact.
foreach ((array) ($res['details'] ?? []) as $d) {
    echo $stamp . '  · ' . ($d['db'] ?? '?') . ' — ' . ($d['status'] ?? '?') . ': ' . ($d['message'] ?? '') . "\n";
}

exit(!empty($res['ran']) && empty($res['success']) ? 1 : 0);
