<?php
declare(strict_types=1);

$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
if ($lane === 'B') {
    $config = include '/tmp/zhct-http-store-mysql.dQTTBP/application/config/local/database.php';
    if (!is_array($config) || ($config['database'] ?? '') !== 'zhct'
        || hash('sha256', (string)($config['hostname'] ?? ''))
            !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e') {
        throw new RuntimeException('B code-local MySQL identity drift');
    }
    $db = new PDO('mysql:host=' . $config['hostname'] . ';port=3306;dbname=zhct;charset=utf8',
        $config['username'], $config['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    $port = 18081;
} else {
    if (getenv('POC_DIALECT') !== 'dm' || getenv('POC_HOST') !== '127.0.0.1'
        || getenv('POC_PORT') !== '5237' || getenv('POC_SCHEMA') !== 'ZHCT_APP'
        || getenv('POC_USER') !== 'ZHCT_APP') {
        throw new RuntimeException('C isolated DM identity drift');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5237;schema=ZHCT_APP',
        getenv('POC_USER'), getenv('POC_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() !== 'ZHCT_APP') {
        throw new RuntimeException('C schema drift');
    }
    $port = 18080;
}
$source = static function (string $sql, array $args = []) use ($db): array {
    $stmt = $db->prepare($sql);
    $stmt->execute($args);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $stmt->fetchAll(PDO::FETCH_ASSOC));
};
$http = static function (string $path, array $form = []) use ($port): array {
    $ctx = stream_context_create(['http' => [
        'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query($form, '', '&', PHP_QUERY_RFC3986),
        'ignore_errors' => true, 'timeout' => 20, 'follow_location' => 0,
    ]]);
    $handle = @fopen('http://127.0.0.1:' . $port . $path, 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated Store HTTP unavailable');
    $raw = stream_get_contents($handle, 4194305);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 4194304) throw new RuntimeException('HTTP response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('business response failed at ' . $path
            . ' code=' . (string)($body['code'] ?? 'nonjson')
            . ' message=' . substr((string)($body['message'] ?? ''), 0, 120));
    }
    return $body;
};
$sportSource = $source('SELECT uuid,puuid,name FROM ydy_sport ORDER BY id ASC');
$sportMap = [];
foreach ($sportSource as $row) $sportMap[(string)$row['uuid']] = $row;
$sportTree = $http('/p/api/sport')['data'] ?? null;
if (!is_array($sportTree) || !$sportTree) throw new RuntimeException('sport tree empty');
$sportShown = 0;
$walkSport = static function (array $nodes) use (&$walkSport, &$sportShown, $sportMap): void {
    foreach ($nodes as $node) {
        $uuid = (string)($node['uuid'] ?? '');
        if (!isset($sportMap[$uuid]) || (string)($node['name'] ?? '') !== (string)$sportMap[$uuid]['name']
            || (string)($node['puuid'] ?? '') !== (string)$sportMap[$uuid]['puuid']) {
            throw new RuntimeException('sport tree node differs from original row');
        }
        $sportShown++;
        if (isset($node['children'])) $walkSport($node['children']);
    }
};
$walkSport($sportTree);
if ($sportShown < 1) throw new RuntimeException('sport tree has no source nodes');
$leafDepartments = $source('SELECT d.uuid FROM ydy_department d'
    . ' JOIN ydy_staff_department sd ON sd.department_uuid=d.uuid'
    . ' JOIN ydy_staff s ON s.uuid=sd.staff_uuid AND s.is_show=1'
    . ' WHERE NOT EXISTS (SELECT 1 FROM ydy_department c WHERE c.puuid=d.uuid)'
    . ' ORDER BY d.id ASC' . ($lane === 'B' ? ' LIMIT 30' : ' FETCH FIRST 30 ROWS ONLY'));
if (!$leafDepartments) throw new RuntimeException('no occupied leaf department');
$departmentUuid = (string)$leafDepartments[0]['uuid'];
$staffSource = $source('SELECT s.uuid,s.name,s.grade FROM ydy_staff s'
    . ' WHERE s.is_show=1 AND s.uuid IN (SELECT sd.staff_uuid FROM ydy_staff_department sd'
    . ' WHERE sd.department_uuid=?) ORDER BY s.id DESC', [$departmentUuid]);
if (!$staffSource) throw new RuntimeException('chosen leaf department has no visible staff');
$sportShow = $http('/p/api/sportShow', ['department_uuid' => $departmentUuid])['data'] ?? null;
if (!is_array($sportShow) || !is_array($sportShow['rows'] ?? null)
    || (int)($sportShow['total'] ?? -1) !== count($staffSource)
    || count($sportShow['rows']) !== count($staffSource)) {
    throw new RuntimeException('department staff totals differ from original table');
}
foreach ($sportShow['rows'] as $index => $row) {
    if ((string)($row['uuid'] ?? '') !== (string)$staffSource[$index]['uuid']
        || (string)($row['name'] ?? '') !== (string)$staffSource[$index]['name']
        || (int)($row['grade'] ?? -1) !== (int)$staffSource[$index]['grade']) {
        throw new RuntimeException('department staff row differs from original table');
    }
}
$dishesSource = $source('SELECT uuid,name,weight FROM ydy_dishes'
    . ' WHERE is_del=1 AND status=1 AND category=1 ORDER BY id DESC');
if (!$dishesSource) throw new RuntimeException('category-one dish source absent');
$dishMap = [];
foreach ($dishesSource as $row) $dishMap[(string)$row['uuid']] = $row;
$selected = $http('/p/api/select', ['category' => 1, 'status' => 1])['data'] ?? null;
if (!is_array($selected) || !is_array($selected['rows'] ?? null)
    || (int)($selected['total'] ?? -1) !== count($dishesSource)
    || count($selected['rows']) !== count($dishesSource)) {
    throw new RuntimeException('selected dish total differs from original table');
}
foreach ($selected['rows'] as $row) {
    $uuid = (string)($row['uuid'] ?? '');
    if (!isset($dishMap[$uuid])
        || (string)($row['name'] ?? '') !== (string)$dishMap[$uuid]['name']
        || (string)($row['weight'] ?? '') !== bcadd((string)$dishMap[$uuid]['weight'], '0', 2)) {
        throw new RuntimeException('selected dish name/weight differs from original row');
    }
}
if ($sportSource !== $source('SELECT uuid,puuid,name FROM ydy_sport ORDER BY id ASC')
    || $dishesSource !== $source('SELECT uuid,name,weight FROM ydy_dishes'
        . ' WHERE is_del=1 AND status=1 AND category=1 ORDER BY id DESC')) {
    throw new RuntimeException('original sport or dish table changed during read');
}
$first = $selected['rows'][0];
$types = [];
foreach ($first as $field => $value) $types[$field] = gettype($value);
ksort($types);
echo json_encode(['lane' => $lane, 'http_business_ok' => 3,
    'sport_source_rows' => count($sportSource), 'sport_tree_nodes' => $sportShown,
    'department_staff_source_rows' => count($staffSource),
    'selected_dish_rows' => count($selected['rows']),
    'select_first_row_type_sha256' => hash('sha256', json_encode($types)),
    'business_dml' => 0], JSON_UNESCAPED_SLASHES), PHP_EOL;
