<?php
declare(strict_types=1);

// A/B/C SELECT-only source/schema/owned-zero gate for future two-worker race.
$lane = (string)getenv('CDX_EM_RACE_LANE');
if (!in_array($lane, ['A', 'B', 'C'], true)
    || count($argv) !== 2 || ($argv[1] ?? '') !== '--preflight-only'
    || (string)getenv('CDX_EM_RACE_PREFLIGHT') !== 'BIND_RACE_SCHEMA_SELECT_ONLY_V1'
    || !hash_equals((string)hash_file('sha256', __FILE__),
        (string)getenv('CDX_EM_RACE_PREFLIGHT_SHA'))) {
    echo json_encode(['status' => 'default-deny', 'db_connected' => false,
        'business_http_sent' => false, 'dml_sent' => false,
        'new_workers_started' => false]), PHP_EOL;
    exit(78);
}
$stage = 'approved_existing_runtime';
set_exception_handler(static function (Throwable $error) use (&$stage): void {
    echo json_encode(['status' => 'redacted_stop', 'stage' => $stage,
        'error_class' => get_class($error), 'code' => (string)$error->getCode(),
        'business_http_sent' => false, 'dml_sent' => false]), PHP_EOL;
    exit(2);
});
$sourceProbe = __DIR__ . '/../parallel-electronic-menu-log-batch-20261004/preflight_log_batch.php';
if ($lane === 'C') {
    $sourceProbe = '/tmp/zhct-emenu-core.1ZcUkR/preflight_log_batch.php';
}
if (!hash_equals('8c619b96c447f849b551b5c7119007fee90a34d9ce623eb05e9027280a87fef9',
    (string)hash_file('sha256', $sourceProbe))) {
    throw new RuntimeException('Approved Store environment probe drift');
}
putenv('CDX_EM_LOG_LANE=' . $lane);
putenv('CDX_EM_LOG_PREFLIGHT=OWNED_DEVICE_LOG_BATCH_SELECT_ONLY_V1');
putenv('CDX_EM_LOG_PREFLIGHT_SHA=8c619b96c447f849b551b5c7119007fee90a34d9ce623eb05e9027280a87fef9');
$outerArgv = $argv;
$argv[1] = '--preflight-only';
ob_start();
require $sourceProbe;
$sourceText = (string)ob_get_clean();
$argv = $outerArgv;
restore_exception_handler();
$source = json_decode(trim($sourceText), true);
if (!is_array($source) || ($source['status'] ?? null) !== 'select_only_pass'
    || ($source['lane'] ?? null) !== $lane
    || ($source['trigger_count'] ?? -1) !== 0
    || ($source['incoming_outgoing_fk_count'] ?? -1) !== 0
    || ($source['auto_id_on_three_tables'] ?? null) !== true) {
    throw new RuntimeException('Existing Store schema gate not clean');
}
$stage = 'bind_code_schema_and_dependencies';
$bind = $dialect === 'dm'
    ? 'YDY_ELECTRONIC_MENU_BIND_CODE' : 'ydy_electronic_menu_bind_code';
$db->query('SELECT ID,MENU_ID,CODE_HASH,EXPIRES_AT,USED_AT,STATUS,'
    . ' STORE_ID,CREATE_BY,CREATE_TIME FROM ' . $bind . ' WHERE 1=0');
if ($dialect === 'mysql') {
    $trigger = (int)$db->query('SELECT COUNT(*) FROM INFORMATION_SCHEMA.TRIGGERS'
        . " WHERE EVENT_OBJECT_SCHEMA=DATABASE()"
        . " AND EVENT_OBJECT_TABLE='ydy_electronic_menu_bind_code'")
        ->fetchColumn();
    $outFk = (int)$db->query('SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE'
        . " WHERE TABLE_SCHEMA=DATABASE()"
        . " AND TABLE_NAME='ydy_electronic_menu_bind_code'"
        . ' AND REFERENCED_TABLE_NAME IS NOT NULL')->fetchColumn();
    $inFk = (int)$db->query('SELECT COUNT(*) FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE'
        . " WHERE REFERENCED_TABLE_SCHEMA=DATABASE()"
        . " AND REFERENCED_TABLE_NAME='ydy_electronic_menu_bind_code'")
        ->fetchColumn();
    $identity = (int)$db->query('SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS'
        . ' WHERE TABLE_SCHEMA=DATABASE()'
        . " AND TABLE_NAME='ydy_electronic_menu_bind_code'"
        . " AND COLUMN_NAME='id' AND EXTRA LIKE '%auto_increment%'")
        ->fetchColumn() === 1;
} else {
    $stage = 'c_bind_trigger';
    $trigger = (int)$db->query('SELECT COUNT(*) FROM USER_TRIGGERS'
        . " WHERE TABLE_NAME='YDY_ELECTRONIC_MENU_BIND_CODE'")->fetchColumn();
    $stage = 'c_bind_outgoing_fk';
    $outFk = (int)$db->query('SELECT COUNT(*) FROM USER_CONSTRAINTS'
        . " WHERE TABLE_NAME='YDY_ELECTRONIC_MENU_BIND_CODE'"
        . " AND CONSTRAINT_TYPE='R'")->fetchColumn();
    $stage = 'c_bind_incoming_fk';
    $inFk = (int)$db->query('SELECT COUNT(*) FROM ALL_CONSTRAINTS c'
        . ' JOIN ALL_CONSTRAINTS p ON c.R_OWNER=p.OWNER'
        . ' AND c.R_CONSTRAINT_NAME=p.CONSTRAINT_NAME'
        . " WHERE c.CONSTRAINT_TYPE='R' AND p.OWNER='ZHCT_APP'"
        . " AND p.TABLE_NAME='YDY_ELECTRONIC_MENU_BIND_CODE'")
        ->fetchColumn();
    $stage = 'c_bind_identity';
    $defStmt = $db->prepare('CALL SP_TABLEDEF(?, ?)');
    $defStmt->execute(['ZHCT_APP', 'YDY_ELECTRONIC_MENU_BIND_CODE']);
    $ddl = $defStmt->fetchColumn();
    if (is_resource($ddl)) $ddl = stream_get_contents($ddl);
    $identity = is_string($ddl) && preg_match(
        '/^\s*"ID"\s+(?:BIGINT|INT|DEC(?:IMAL)?\(\d+\s*,\s*0\))\s+'
        . '(?:AUTO_INCREMENT|IDENTITY)\b/im', $ddl) === 1;
}
if ($trigger !== 0 || $outFk !== 0 || $inFk !== 0 || !$identity) {
    throw new RuntimeException('Bind-code trigger/FK/identity boundary not clean');
}
$stage = 'collision_prevention_unique_indexes';
if ($dialect === 'mysql') {
    $indexRows = $db->query('SELECT TABLE_NAME,INDEX_NAME,NON_UNIQUE,'
        . ' COLUMN_NAME,SEQ_IN_INDEX FROM INFORMATION_SCHEMA.STATISTICS'
        . ' WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME IN ('
        . "'ydy_electronic_menu_bind_code','ydy_electronic_menu_device')"
        . ' ORDER BY TABLE_NAME,INDEX_NAME,SEQ_IN_INDEX')->fetchAll(PDO::FETCH_ASSOC);
} else {
    $indexRows = $db->query('SELECT i.TABLE_NAME,i.INDEX_NAME,i.UNIQUENESS,'
        . ' c.COLUMN_NAME,c.COLUMN_POSITION AS SEQ_IN_INDEX'
        . ' FROM USER_INDEXES i JOIN USER_IND_COLUMNS c'
        . ' ON c.INDEX_NAME=i.INDEX_NAME AND c.TABLE_NAME=i.TABLE_NAME'
        . " WHERE i.TABLE_NAME IN ('YDY_ELECTRONIC_MENU_BIND_CODE',"
        . "'YDY_ELECTRONIC_MENU_DEVICE')"
        . ' ORDER BY i.TABLE_NAME,i.INDEX_NAME,c.COLUMN_POSITION')
        ->fetchAll(PDO::FETCH_ASSOC);
}
$uniqueIndexes = [];
foreach ($indexRows as $row) {
    $tableName = strtoupper((string)$row['table_name']);
    $indexName = strtoupper((string)$row['index_name']);
    $isUnique = $dialect === 'mysql'
        ? (int)$row['non_unique'] === 0
        : strtoupper((string)$row['uniqueness']) === 'UNIQUE';
    if ($isUnique) {
        $uniqueIndexes[$tableName][$indexName][(int)$row['seq_in_index']]
            = strtoupper((string)$row['column_name']);
    }
}
$bindCodeUnique = false;
$deviceIdentityUnique = false;
foreach ($uniqueIndexes['YDY_ELECTRONIC_MENU_BIND_CODE'] ?? [] as $columns) {
    ksort($columns);
    if (array_values($columns) === ['CODE_HASH']) $bindCodeUnique = true;
}
foreach ($uniqueIndexes['YDY_ELECTRONIC_MENU_DEVICE'] ?? [] as $columns) {
    ksort($columns);
    if (array_values($columns) === ['STORE_ID', 'DEVICE_ID']) {
        $deviceIdentityUnique = true;
    }
}
if (!$bindCodeUnique || !$deviceIdentityUnique) {
    throw new RuntimeException('Binding/device collision unique indexes absent');
}
$stage = 'old_race_marker_zero';
$menu = $dialect === 'dm' ? 'YDY_ELECTRONIC_MENU' : 'ydy_electronic_menu';
$device = $dialect === 'dm'
    ? 'YDY_ELECTRONIC_MENU_DEVICE' : 'ydy_electronic_menu_device';
$logs = $dialect === 'dm'
    ? 'YDY_ELECTRONIC_MENU_DEVICE_LOG' : 'ydy_electronic_menu_device_log';
$owned = [
    'menu' => (int)$db->query('SELECT COUNT(*) FROM ' . $menu
        . " WHERE CREATE_BY LIKE 'CDXEMRACE%'")->fetchColumn(),
    'bind' => (int)$db->query('SELECT COUNT(*) FROM ' . $bind
        . " WHERE CREATE_BY LIKE 'CDXEMRACE%'")->fetchColumn(),
    'device' => (int)$db->query('SELECT COUNT(*) FROM ' . $device
        . " WHERE DEVICE_ID LIKE 'CDXEMRACE%'"
        . " OR CREATE_BY LIKE 'CDXEMRACE%'")->fetchColumn(),
    'log' => (int)$db->query('SELECT COUNT(*) FROM ' . $logs
        . " WHERE CREATE_BY LIKE 'device:CDXEMRACE%'")->fetchColumn(),
];
if (array_sum($owned) !== 0) {
    throw new RuntimeException('Old synthetic race fixture present');
}
echo json_encode(['status' => 'select_only_pass', 'lane' => $lane,
    'database' => $dialect === 'dm' ? 'nonproduction_store_dm'
        : 'code_local_dev_mysql',
    'existing_http_workers_per_listener' => 1,
    'second_worker_currently_started' => false,
    'bind_table_count' => (int)$db->query('SELECT COUNT(*) FROM ' . $bind)
        ->fetchColumn(),
    'bind_triggers' => $trigger, 'bind_outgoing_fk' => $outFk,
    'bind_incoming_fk' => $inFk, 'bind_id_auto' => $identity,
    'bind_code_hash_unique' => $bindCodeUnique,
    'store_device_id_unique' => $deviceIdentityUnique,
    'old_owned_markers' => $owned,
    'business_http_sent' => false, 'dml_sent' => false],
    JSON_UNESCAPED_SLASHES), PHP_EOL;
