<?php
declare(strict_types=1);

// Read-only preflight for a single, synthetic Store meal-order wide-ID experiment.
$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    throw new RuntimeException('Only B/C isolated lanes are accepted');
}
$root = $lane === 'B' ? '/tmp/zhct-http-store-mysql.dQTTBP'
    : '/tmp/zhct-dm-poc-20260928.fcpiiN/store';
$base = $lane === 'B' ? 'http://127.0.0.1:18081' : 'http://127.0.0.1:18080';
$body = @file_get_contents($base . '/__poc_boundary', false,
    stream_context_create(['http' => ['timeout' => 4]]));
$boundary = is_string($body) ? json_decode($body, true) : null;
if (!is_array($boundary) || empty($boundary['external_stubs'])
    || empty($boundary['redis_isolated']) || !empty($boundary['real_queue'])) {
    throw new RuntimeException('Isolated HTTP boundary not confirmed');
}
$config = require $root . '/application/database.php';
if (($config['database'] ?? '') !== ($lane === 'B' ? 'zhct' : 'ZHCT_APP')
    || ($config['prefix'] ?? '') !== 'ydy_') {
    throw new RuntimeException('Unexpected Store database configuration');
}
if ($lane === 'B') {
    $local = require '/workspace/zhct/zhctproject/store/application/config/local/database.php';
    foreach (['hostname', 'database', 'username', 'password'] as $key) {
        if (($local[$key] ?? null) !== ($config[$key] ?? null)) {
            throw new RuntimeException('B worker differs from code-local development database');
        }
    }
} elseif (($config['hostname'] ?? '') !== '127.0.0.1'
    || (int)($config['hostport'] ?? 0) !== 5237) {
    throw new RuntimeException('C worker differs from isolated Store DM instance');
}
$dsn = $lane === 'B'
    ? 'mysql:host=' . $config['hostname'] . ';port=' . ($config['hostport'] ?? 3306)
        . ';dbname=' . $config['database'] . ';charset=utf8'
    : 'dm:host=' . $config['hostname'] . ';port=' . $config['hostport']
        . ';schema=' . $config['database'];
$db = new PDO($dsn, $config['username'], $config['password'], [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_CASE => PDO::CASE_LOWER,
]);
$table = $lane === 'B' ? 'ydy_' : 'YDY_';
$sourceSql = 'SELECT u.ID AS USER_ID,u.TYPE AS USER_TYPE,u.ACCOUNT,u.UUID AS USER_UUID,'
    . 'm.ID AS ORDER_ID,m.RESTAURANT_ID,m.ORDER_NO,m.MSGID'
    . ' FROM ' . $table . 'user u JOIN ' . $table . 'meal_order m'
    . ' ON m.USER_ID=u.ID AND m.MSGID=u.ACCOUNT'
    . " WHERE u.ACCOUNT LIKE 'CDXPAY%' AND u.UUID LIKE 'CDXUSER-%'"
    . ' AND m.IS_DELETE=0 AND m.RESTAURANT_ID>0 ORDER BY m.ID';
$sources = $db->query($sourceSql)->fetchAll();
$safeSources = [];
foreach ($sources as $row) {
    if (!preg_match('/^CDXPAY[A-F0-9]{8}$/D', (string)$row['account'])
        || (string)$row['msgid'] !== (string)$row['account']) continue;
    $safeSources[] = [
        'user_id' => (int)$row['user_id'], 'user_type' => (int)$row['user_type'],
        'order_id' => (int)$row['order_id'],
        'restaurant_id' => (int)$row['restaurant_id'],
        'account_sha256' => hash('sha256', (string)$row['account']),
    ];
}
$metaSql = $lane === 'B'
    ? "SELECT COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,IS_NULLABLE,COLUMN_DEFAULT,EXTRA"
        . " FROM information_schema.COLUMNS WHERE TABLE_SCHEMA=DATABASE()"
        . " AND TABLE_NAME='ydy_meal_order' ORDER BY ORDINAL_POSITION"
    : "SELECT COLUMN_NAME,DATA_TYPE,DATA_PRECISION,DATA_SCALE,NULLABLE,DATA_DEFAULT"
        . " FROM USER_TAB_COLUMNS WHERE TABLE_NAME='YDY_MEAL_ORDER' ORDER BY COLUMN_ID";
$metadata = $db->query($metaSql)->fetchAll();
$wide = [];
$required = [];
foreach ($metadata as $row) {
    $name = strtolower((string)$row['column_name']);
    if ($name === 'account_settlement_id' || $name === 'id'
        || $name === 'order_no' || $name === 'msgid'
        || $name === 'pay_status' || $name === 'print_status') $wide[$name] = $row;
    $notNull = $lane === 'B' ? ($row['is_nullable'] ?? '') === 'NO'
        : ($row['nullable'] ?? '') === 'N';
    $default = $lane === 'B' ? ($row['column_default'] ?? null) : ($row['data_default'] ?? null);
    $identity = $lane === 'B' ? strpos((string)($row['extra'] ?? ''), 'auto_increment') !== false
        : $name === 'id'; // DM USER_TAB_COLUMNS has no IDENTITY_COLUMN on this build.
    if ($notNull && $default === null && !$identity) $required[] = $name;
}
$triggerSql = $lane === 'B'
    ? "SELECT COUNT(*) FROM information_schema.TRIGGERS WHERE TRIGGER_SCHEMA=DATABASE()"
        . " AND EVENT_OBJECT_TABLE='ydy_meal_order'"
    : "SELECT COUNT(*) FROM USER_TRIGGERS WHERE TABLE_NAME='YDY_MEAL_ORDER'";
$triggers = (int)$db->query($triggerSql)->fetchColumn();
$foreignSql = $lane === 'B'
    ? "SELECT COUNT(*) FROM information_schema.KEY_COLUMN_USAGE WHERE TABLE_SCHEMA=DATABASE()"
        . " AND TABLE_NAME='ydy_meal_order' AND REFERENCED_TABLE_NAME IS NOT NULL"
    : "SELECT COUNT(*) FROM USER_CONSTRAINTS WHERE TABLE_NAME='YDY_MEAL_ORDER' AND CONSTRAINT_TYPE='R'";
$foreign = (int)$db->query($foreignSql)->fetchColumn();
$markerCount = (int)$db->query("SELECT COUNT(*) FROM " . $table . "meal_order"
    . " WHERE ORDER_NO LIKE 'CDXWIDE%'")->fetchColumn();
echo json_encode([
    'lane' => $lane, 'boundary' => true, 'source_candidates' => $safeSources,
    'meal_order_column_count' => count($metadata),
    'required_without_default' => $required,
    'wide_and_guard_columns' => $wide,
    'triggers' => $triggers, 'foreign_keys' => $foreign,
    'existing_marker_rows' => $markerCount,
], JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), PHP_EOL;
