<?php
declare(strict_types=1);

// Read-only gate for the isolated B/C workers. Prints no credentials or row values.
$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    fwrite(STDERR, "DENIED: lane B or C required\n");
    exit(78);
}
$root = $lane === 'B' ? '/private/tmp/zhct-http-ai-macos.x2CCZX'
    : '/tmp/zhct-ai-http-20260929.3XDj3w';
$pid = $lane === 'B' ? 13127 : 53772;
$port = $lane === 'B' ? 18101 : 18102;
$files = [
    'app/store/controller/goods/Service.php',
    'app/store/controller/goods/Spec.php',
    'app/store/model/goods/Service.php',
    'app/common/model/GoodsSpecRel.php',
];
foreach ($files as $file) {
    if (!is_file($root . '/' . $file)) {
        throw new RuntimeException('Worker source absent: ' . $file);
    }
}
if ($lane === 'B') {
    $cfg = parse_ini_file('/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local', true, INI_SCANNER_RAW)['DATABASE'] ?? null;
    $ps = (string)shell_exec('/bin/ps eww -p ' . $pid . ' -o command=');
    $owner = trim((string)shell_exec('/usr/sbin/lsof -nP -t -iTCP:' . $port . ' -sTCP:LISTEN 2>/dev/null'));
    if (!is_array($cfg) || strtolower((string)($cfg['TYPE'] ?? '')) !== 'mysql'
        || (string)($cfg['HOSTPORT'] ?? '') !== '3306' || $owner !== (string)$pid
        || strpos($ps, 'POC_DIALECT=mysql') === false
        || strpos($ps, 'POC_EXTERNAL_STUBS=1') === false) {
        throw new RuntimeException('B worker/config drift');
    }
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT', 'DATABASE' => 'SCHEMA',
              'USERNAME' => 'USER', 'PASSWORD' => 'PASSWORD'] as $from => $to) {
        $value = (string)($cfg[$from] ?? '');
        if ($value === '' || strpos($ps, 'POC_AI_' . $to . '=' . $value) === false) {
            throw new RuntimeException('B worker differs from code local config');
        }
    }
    $db = new PDO('mysql:host=' . $cfg['HOSTNAME'] . ';port=' . $cfg['HOSTPORT']
        . ';dbname=' . $cfg['DATABASE'] . ';charset=utf8', $cfg['USERNAME'], $cfg['PASSWORD'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
} else {
    $env = [];
    foreach (explode("\0", (string)file_get_contents('/proc/' . $pid . '/environ')) as $item) {
        $pair = explode('=', $item, 2);
        if (count($pair) === 2) $env[$pair[0]] = $pair[1];
    }
    if (($env['POC_TARGET_ROOT'] ?? '') !== $root
        || ($env['POC_BASE_URL'] ?? '') !== 'http://127.0.0.1:' . $port
        || ($env['POC_DIALECT'] ?? '') !== 'dm'
        || ($env['POC_EXTERNAL_STUBS'] ?? '') !== '1'
        || ($env['POC_AI_HOST'] ?? '') !== '127.0.0.1'
        || ($env['POC_AI_PORT'] ?? '') !== '5238'
        || ($env['POC_AI_SCHEMA'] ?? '') !== 'AIZHCT_APP'
        || ($env['POC_AI_USER'] ?? '') !== 'AIZHCT_APP'
        || !in_array('dm', PDO::getAvailableDrivers(), true)) {
        throw new RuntimeException('C worker/config drift');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP',
        $env['POC_AI_USER'], $env['POC_AI_PASSWORD'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    if ($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn() !== 'AIZHCT_APP') {
        throw new RuntimeException('C schema drift');
    }
}
$t = static function (string $logical) use ($lane): string {
    $allowed = ['goods', 'goods_service', 'goods_spec_rel', 'spec', 'spec_value'];
    if (!in_array($logical, $allowed, true)) throw new RuntimeException('Unknown table');
    return 'yoshop_' . ($lane === 'B' ? $logical : strtoupper($logical));
};
$pk = ['goods' => 'GOODS_ID', 'goods_service' => 'SERVICE_ID',
    'goods_spec_rel' => 'ID', 'spec' => 'SPEC_ID', 'spec_value' => 'SPEC_VALUE_ID'];
$tables = [];
foreach ($pk as $logical => $column) {
    $s = $db->query('SELECT * FROM ' . $t($logical)
        . ' WHERE STORE_ID=10001 ORDER BY ' . $column);
    $h = hash_init('sha256');
    $count = 0;
    while (($row = $s->fetch(PDO::FETCH_NUM)) !== false) {
        hash_update($h, serialize($row));
        if (++$count > 30000) throw new RuntimeException('Source cap exceeded');
    }
    $tables[$logical] = ['count' => $count, 'sha256' => hash_final($h)];
}
$activeServices = $db->query('SELECT SERVICE_ID FROM ' . $t('goods_service')
    . ' WHERE STORE_ID=10001 AND IS_DELETE=0 ORDER BY SERVICE_ID')->fetchAll(PDO::FETCH_COLUMN);
$goodsWithSpecs = $db->query('SELECT DISTINCT r.GOODS_ID FROM ' . $t('goods_spec_rel') . ' r'
    . ' JOIN ' . $t('goods') . ' g ON g.GOODS_ID=r.GOODS_ID'
    . ' AND g.STORE_ID=10001 AND g.IS_DELETE=0'
    . ' JOIN ' . $t('spec') . ' s ON s.SPEC_ID=r.SPEC_ID'
    . ' JOIN ' . $t('spec_value') . ' v ON v.SPEC_VALUE_ID=r.SPEC_VALUE_ID'
    . ' WHERE r.STORE_ID=10001 ORDER BY r.GOODS_ID')->fetchAll(PDO::FETCH_COLUMN);
$sourceSha = [];
foreach ($files as $file) $sourceSha[$file] = hash_file('sha256', $root . '/' . $file);
echo json_encode(['lane' => $lane, 'worker_port' => $port, 'source_sha256' => $sourceSha,
    'tables' => $tables, 'active_service_count' => count($activeServices),
    'service_sample_ids' => array_slice(array_map('intval', $activeServices), 0, 3),
    'goods_with_specs_count' => count($goodsWithSpecs),
    'goods_with_specs_sample_ids' => array_slice(array_map('intval', $goodsWithSpecs), 0, 3),
    'business_http' => 0, 'business_dml' => 0], JSON_UNESCAPED_SLASHES), "\n";
