<?php

declare(strict_types=1);

$root = getenv('POC_APP_ROOT');
$host = getenv('POC_HOST');
$port = (int)getenv('POC_PORT');
$database = getenv('POC_SCHEMA');
$user = getenv('POC_USER');
$password = getenv('POC_PASSWORD');
$lockFile = getenv('POC_ADVISORY_FILE');
if (!$root || !$host || $port < 1 || !$database || !$user || !$password || !$lockFile || !is_file($lockFile)) exit(2);
define('APP_PATH', $root . '/application/');
require $root . '/thinkphp/base.php';
require $lockFile;
if (!function_exists('config')) {
    function config($name = '', $value = null, $range = '')
    {
        return $value === null ? \think\Config::get($name) : \think\Config::set($name, $value, $range);
    }
}

\think\Config::set([
    'type' => 'mysql',
    'hostname' => $host,
    'hostport' => $port,
    'database' => $database,
    'username' => $user,
    'password' => $password,
    'prefix' => 'ydy_',
], 'database');
$second = new PDO("mysql:host=$host;port=$port;dbname=$database;charset=utf8mb4", $user, $password, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
$name = 'codex:framework-lock:' . bin2hex(random_bytes(5));
$acquired = false;
try {
    $acquired = \app\common\service\database\AdvisoryLock::acquire($name, 0);
    if (!$acquired) throw new RuntimeException('Framework failed to acquire MySQL lock');
    $request = $second->prepare('SELECT GET_LOCK(?,0)');
    $request->execute([$name]);
    if ((int)$request->fetchColumn() !== 0) throw new RuntimeException('Competing session was not busy');
    \app\common\service\database\AdvisoryLock::release($name);
    $acquired = false;
    $request->execute([$name]);
    if ((int)$request->fetchColumn() !== 1) throw new RuntimeException('Competing session could not acquire released lock');
    $release = $second->prepare('SELECT RELEASE_LOCK(?)');
    $release->execute([$name]);
    if ((int)$release->fetchColumn() !== 1) throw new RuntimeException('Competing session could not release lock');
    echo json_encode(['framework_lock' => 'passed', 'competing_session' => 'busy_then_acquired']) . PHP_EOL;
} finally {
    if ($acquired) \app\common\service\database\AdvisoryLock::release($name);
}
