<?php
declare(strict_types=1);

// SELECT-only natural-source preflight for three current-PC Ontoanalysis reads.
$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    exit(78);
}
$target = $lane === 'B'
    ? ['/tmp/zhct-http-store-mysql.dQTTBP', 'http://127.0.0.1:18081', 10001,
        '003eb5aecf1cd4595b609c1f7f20b9ee325b578309fb9fe14fedaf77584fa401']
    : ['/tmp/zhct-dm-poc-20260928.fcpiiN/store', 'http://127.0.0.1:18080', 112175,
        'bc98485aed26beab348770a82ae38dbf922b04ab88a210cd7282c4caf0156194'];
[$root, $base, $pid, $expectedIdentitySha] = $target;
$stage = 'entry';
try {
    $cmdline = (string)@file_get_contents('/proc/' . $pid . '/cmdline');
    $children = trim((string)@file_get_contents('/proc/' . $pid . '/task/' . $pid . '/children'));
    $boundary = json_decode((string)@file_get_contents($base . '/__poc_boundary'), true);
    if (strpos($cmdline, $root . '/public') === false
        || strpos($cmdline, (string)parse_url($base, PHP_URL_PORT)) === false
        || $children !== '' || !is_array($boundary)
        || empty($boundary['external_stubs']) || empty($boundary['redis_isolated'])
        || !empty($boundary['real_queue'])) {
        throw new RuntimeException('worker boundary');
    }
    $stage = 'runtime-config';
    $config = require $root . '/application/database.php';
    if (!is_array($config) || ($config['prefix'] ?? '') !== 'ydy_'
        || ($config['ai_zhct']['prefix'] ?? '') !== 'yoshop_') {
        throw new RuntimeException('database config');
    }
    $dialect = $lane === 'C' ? 'dm' : 'mysql';
    $storeDsn = $dialect === 'dm' ? 'dm:host=127.0.0.1;port=5237;schema=ZHCT_APP'
        : 'mysql:host=' . $config['hostname'] . ';port=' . ($config['hostport'] ?? 3306)
            . ';dbname=' . $config['database'] . ';charset=utf8mb4';
    $aiConfig = $config['ai_zhct'];
    $aiDsn = $dialect === 'dm' ? 'dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP'
        : 'mysql:host=' . ($aiConfig['hostname'] ?? $config['hostname'])
            . ';port=' . ($aiConfig['hostport'] ?? 3306)
            . ';dbname=' . $aiConfig['database'] . ';charset=utf8mb4';
    $options = [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5];
    $stage = 'db-connect';
    $store = new PDO($storeDsn, (string)$config['username'], (string)$config['password'], $options);
    $ai = new PDO($aiDsn, (string)$aiConfig['username'], (string)$aiConfig['password'], $options);
    $identity = $dialect === 'dm'
        ? 'ZHCT_APP|5237|' . (string)$store->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()
        : (string)$store->query("SELECT CONCAT(@@server_uuid,'|',@@hostname,'|',@@port,'|',DATABASE())")->fetchColumn();
    if (!hash_equals($expectedIdentitySha, hash('sha256', $identity))) {
        throw new RuntimeException('store identity');
    }
    if ($dialect === 'dm' && ((string)$ai->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn()) !== 'AIZHCT_APP') {
        throw new RuntimeException('AI identity');
    }
    $st = $dialect === 'dm' ? 'YDY_' : 'ydy_';
    $at = $dialect === 'dm' ? 'YOSHOP_' : 'yoshop_';
    $stage = 'natural-source';
    $sql = 'SELECT S.USER_ID AS U, M.MEAL_DATE AS D, COUNT(*) AS N FROM ' . $at . 'meal M'
        . ' JOIN ' . $at . 'staff S ON S.ID=M.STAFF_ID'
        . ' JOIN ' . $at . 'meal_infos I ON I.MEAL_ID=M.ID'
        . ' WHERE M.STORE_ID=10001 AND M.IS_DELETE=0 AND S.STORE_ID=10001'
        . ' AND S.IS_DELETE=0 AND I.STORE_ID=10001 AND I.IS_DELETE=0 AND S.USER_ID>0'
        . ' GROUP BY S.USER_ID,M.MEAL_DATE ORDER BY N DESC,U';
    $candidates = $ai->query($sql)->fetchAll(PDO::FETCH_ASSOC);
    if (count($candidates) < 1 || count($candidates) > 20000) {
        throw new RuntimeException('AI source count');
    }
    $staffQuery = $store->prepare('SELECT UUID FROM ' . $st . 'staff WHERE AI_USER_ID=? AND IS_SHOW=1 ORDER BY ID');
    $departmentQuery = $store->prepare('SELECT D.UUID AS D FROM ' . $st . 'staff_department SD'
        . ' JOIN ' . $st . 'department D ON D.UUID=SD.DEPARTMENT_UUID'
        . ' WHERE SD.STAFF_UUID=? AND D.STATUS=1 AND D.IS_SHOW=1 ORDER BY D.ID');
    $childQuery = $store->prepare('SELECT COUNT(*) FROM ' . $st . 'department WHERE PUUID=? AND STATUS=1 AND IS_SHOW=1');
    $menuQuery = $store->prepare('SELECT R.MENU_DATE AS D FROM ' . $st . 'menu_recommend R'
        . ' JOIN ' . $st . 'date_menu DM ON DM.RECOMMEND_UUID=R.UUID'
        . ' WHERE R.STAFF_UUID=? ORDER BY R.MENU_DATE DESC');
    $choice = null;
    $overlap = 0;
    foreach ($candidates as $candidate) {
        $staffQuery->execute([(int)$candidate['u']]);
        $staffUuid = $staffQuery->fetchColumn();
        if (!is_string($staffUuid) || $staffUuid === '') continue;
        $overlap++;
        $departmentQuery->execute([$staffUuid]);
        $department = '';
        foreach ($departmentQuery->fetchAll(PDO::FETCH_ASSOC) as $departmentRow) {
            $candidateDepartment = (string)$departmentRow['d'];
            $childQuery->execute([$candidateDepartment]);
            if ((int)$childQuery->fetchColumn() === 0) {
                $department = $candidateDepartment;
                break;
            }
        }
        if ($department === '') continue;
        $menuQuery->execute([$staffUuid]);
        $menuDate = $menuQuery->fetchColumn();
        if (!is_string($menuDate) || !preg_match('/^\d{4}-\d{2}-\d{2}/', $menuDate)) continue;
        $mealDate = (string)$candidate['d'];
        if (!preg_match('/^\d{4}-\d{2}-\d{2}/', $mealDate)) continue;
        $choice = ['staff_sha12' => substr(hash('sha256', $staffUuid), 0, 12),
            'department_sha12' => substr(hash('sha256', $department), 0, 12),
            'meal_date' => substr($mealDate, 0, 10), 'menu_date' => substr($menuDate, 0, 10),
            'ai_meal_infos_for_day' => (int)$candidate['n']];
        break;
    }
    if (!$choice) throw new RuntimeException('same-person positive window absent');
    echo json_encode(['status' => 'preflight-pass', 'lane' => $lane,
        'ai_candidate_days' => count($candidates), 'store_overlap_examined' => $overlap,
        'choice' => $choice], JSON_UNESCAPED_SLASHES), PHP_EOL;
} catch (Throwable $error) {
    echo json_encode(['status' => 'preflight-blocked', 'lane' => $lane,
        'stage' => $stage, 'class' => get_class($error),
        'code' => (string)$error->getCode(),
        'message_sha12' => substr(hash('sha256', $error->getMessage()), 0, 12)]), PHP_EOL;
    exit(2);
}
