<?php

declare(strict_types=1);

set_exception_handler(static function (Throwable $error): void {
    $info = $error instanceof PDOException ? $error->errorInfo : [];
    fwrite(STDERR, 'N3_MYSQL_METADATA_FAILED ' . get_class($error)
        . ' sqlstate=' . (string)($info[0] ?? $error->getCode()) . PHP_EOL);
    exit(2);
});

$localPath = '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local';
if (realpath((string)getenv('POC_MYSQL_LOCAL_ENV')) !== realpath($localPath)) {
    throw new RuntimeException('Only code local DB allowed');
}
$local = parse_ini_file($localPath, true, INI_SCANNER_RAW);
if (!is_array($local) || !isset($local['DATABASE'], $local['DATABASE_ZHCT'])) {
    throw new RuntimeException('Code local two-business-DB config absent');
}
$root = '/tmp/zhct-http-ai-macos.x2CCZX';
$pid = 13127;
if (trim((string)shell_exec('lsof -nP -iTCP:18101 -sTCP:LISTEN -t 2>/dev/null')) !== (string)$pid) {
    throw new RuntimeException('B listener changed');
}
$process = (string)shell_exec('ps eww -p ' . $pid . ' -o command=');
if (strpos($process, $root . '/public') === false
    || strpos($process, 'php -S 127.0.0.1:18101') === false) {
    throw new RuntimeException('B process identity mismatch');
}
$expected = [
    'POC_TARGET_ROOT' => $root,
    'POC_BASE_URL' => 'http://127.0.0.1:18101',
    'POC_DIALECT' => 'mysql',
];
foreach (['DATABASE' => 'POC_AI_', 'DATABASE_ZHCT' => 'POC_'] as $section => $prefix) {
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT',
        'DATABASE' => 'SCHEMA', 'USERNAME' => 'USER',
        'PASSWORD' => 'PASSWORD'] as $from => $to) {
        $expected[$prefix . $to] = (string)$local[$section][$from];
    }
}
foreach ($expected as $key => $value) {
    $pattern = '/(?:^|\s)' . preg_quote($key, '/') . '=([^\s]*)/';
    if (!preg_match($pattern, $process, $match) || $match[1] !== $value) {
        throw new RuntimeException('B HTTP DB differs from code local');
    }
}
$x = $local['DATABASE'];
$db = new PDO('mysql:host=' . $x['HOSTNAME'] . ';port=' . ($x['HOSTPORT'] ?? 3306)
    . ';dbname=' . $x['DATABASE'] . ';charset=utf8', $x['USERNAME'],
    $x['PASSWORD'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5]);
if ((string)$db->query('SELECT DATABASE()')->fetchColumn() !== (string)$x['DATABASE']) {
    throw new RuntimeException('B effective AI schema mismatch');
}
$stmt = $db->prepare('SELECT COLUMN_NAME,DATA_TYPE,NUMERIC_PRECISION,NUMERIC_SCALE,IS_NULLABLE'
    . ' FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?'
    . ' ORDER BY ORDINAL_POSITION');
$stmt->execute(['yoshop_staff_weight']);
$columns = [];
foreach ($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
    $name = strtolower((string)$row['column_name']);
    if (preg_match('/DECIMAL|NUMERIC|DOUBLE|FLOAT|INTEGER|BIGINT|SMALLINT|TINYINT|INT/i',
            (string)$row['data_type'])
        || in_array($name, ['height', 'weight', 'body_fat_rate', 'bmi'], true)) {
        $columns[$name] = [
            'type' => strtoupper((string)$row['data_type']),
            'precision' => $row['numeric_precision'] === null ? null : (int)$row['numeric_precision'],
            'scale' => $row['numeric_scale'] === null ? null : (int)$row['numeric_scale'],
            'nullable' => (string)$row['is_nullable'],
        ];
    }
}
$casts = [];
foreach (['whole' => '60.00', 'fractional' => '60.25'] as $label => $literal) {
    $value = $db->query('SELECT CAST(' . $literal
        . ' AS DECIMAL(5,2))')->fetchColumn();
    $casts[$label] = [
        'php_type' => gettype($value),
        'fixed_2_decimal_string' => is_string($value)
            && preg_match('/^-?[0-9]+\.[0-9]{2}$/D', $value) === 1,
    ];
}
echo json_encode(['table' => 'yoshop_staff_weight',
    'numeric_like_columns' => $columns, 'synthetic_decimal_cast' => $casts],
    JSON_UNESCAPED_SLASHES) . PHP_EOL;
