<?php
declare(strict_types=1);

// Four Store device/basic-dictionary routes, original-table reads only.
$lane = (string)($argv[1] ?? '');
if (!in_array($lane, ['B', 'C'], true)) {
    echo "DENIED business_http=0 business_dml=0\n"; exit(78);
}
if ($lane === 'B') {
    $c = include '/tmp/zhct-http-store-mysql.dQTTBP/application/config/local/database.php';
    if (!is_array($c) || ($c['database'] ?? '') !== 'zhct')
        throw new RuntimeException('B code-local Store DB drift');
    $db = new PDO('mysql:host=' . $c['hostname'] . ';port=3306;dbname='
        . $c['database'] . ';charset=utf8', $c['username'], $c['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')
        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;
}
$http = static function (string $action, string $method = 'GET',
    string $form = '', bool $direct = false) use ($port): array {
    if (!in_array($method, ['GET', 'POST'], true))
        throw new RuntimeException('Unsupported test method');
    $options = ['method' => $method, 'ignore_errors' => true,
        'timeout' => 25, 'follow_location' => 0];
    if ($method === 'POST') {
        $options['header'] = "Content-Type: application/x-www-form-urlencoded\r\n";
        $options['content'] = $form;
    }
    $ctx = stream_context_create(['http' => $options]);
    $h = @fopen('http://127.0.0.1:' . $port . '/p/api/' . $action,
        'rb', false, $ctx);
    if (!is_resource($h)) throw new RuntimeException('Isolated Store HTTP absent');
    $raw = stream_get_contents($h, 8388609); fclose($h);
    if (!is_string($raw) || strlen($raw) > 8388608)
        throw new RuntimeException('Store response over cap');
    $body = json_decode($raw, true);
    if (!is_array($body))
        throw new RuntimeException('Store route returned non-JSON: ' . $action);
    if ($direct) return $body;
    if ((int)($body['code'] ?? -1) !== 0)
        throw new RuntimeException('Store route business response failed: ' . $action);
    return $body['data'] ?? [];
};
$departments = $http('getDepartmentList', 'POST');
$sourceDepartments = [];
foreach ($db->query('SELECT uuid,puuid,name FROM ydy_department'
    . ' WHERE is_show=1 AND status=1')->fetchAll(PDO::FETCH_ASSOC) as $row) {
    $row = array_change_key_case($row, CASE_LOWER);
    $sourceDepartments[(string)$row['uuid']] = [(string)$row['puuid'], (string)$row['name']];
}
$stack = $departments;
$seen = [];
while ($stack) {
    $node = array_pop($stack);
    if (!is_array($node)) throw new RuntimeException('Department tree node not object');
    $uuid = (string)($node['uuid'] ?? '');
    if ($uuid === '' || isset($seen[$uuid]) || !isset($sourceDepartments[$uuid])
        || $sourceDepartments[$uuid] !== [(string)($node['puuid'] ?? ''),
            (string)($node['name'] ?? '')]) {
        throw new RuntimeException('Department tree node differs from original table');
    }
    $seen[$uuid] = true;
    foreach (($node['children'] ?? []) as $child) $stack[] = $child;
}
if (count($seen) > count($sourceDepartments))
    throw new RuntimeException('Department tree exceeds active source rows');
$sports = $http('getSportEvent', 'POST');
$sourceSports = [];
foreach ($db->query("SELECT name,uuid,puuid FROM ydy_sport WHERE puuid='0'")
    ->fetchAll(PDO::FETCH_ASSOC) as $row) {
    $row = array_change_key_case($row, CASE_LOWER);
    $sourceSports[(string)$row['uuid']] = [(string)$row['puuid'], (string)$row['name']];
}
if (count($sports) !== count($sourceSports))
    throw new RuntimeException('Sport roots count differs from original table');
foreach ($sports as $item) {
    $uuid = (string)($item['uuid'] ?? '');
    if (!isset($sourceSports[$uuid]) || $sourceSports[$uuid] !==
        [(string)($item['puuid'] ?? ''), (string)($item['name'] ?? '')]) {
        throw new RuntimeException('Sport root differs from original table');
    }
}
$dishes = $http('all_dish', 'GET');
$dishesPost = $http('all_dish', 'POST');
if ($dishesPost !== $dishes)
    throw new RuntimeException('All-dish GET and POST contract differs');
$sourceDishRows = $db->query('SELECT uuid,name FROM ydy_dishes WHERE is_del=1')
    ->fetchAll(PDO::FETCH_ASSOC);
$sourceDishes = [];
foreach ($sourceDishRows as $row) {
    $row = array_change_key_case($row, CASE_LOWER);
    $key = (string)$row['uuid'] . "\0" . (string)$row['name'];
    $sourceDishes[$key] = ($sourceDishes[$key] ?? 0) + 1;
}
if (count($dishes) !== count($sourceDishRows))
    throw new RuntimeException('All-dish count differs from original table');
foreach ($dishes as $item) {
    $key = (string)($item['uuid'] ?? '') . "\0" . (string)($item['name'] ?? '');
    if (($sourceDishes[$key] ?? 0) <= 0)
        throw new RuntimeException('Dish entry differs from original table');
    $sourceDishes[$key]--;
}
$hardware = $http('getAllHardwareDishes', 'GET');
$sourceHardwareCount = (int)$db->query('SELECT COUNT(*) FROM ydy_dishes_hardware_img')
    ->fetchColumn();
if (count($hardware) !== $sourceHardwareCount)
    throw new RuntimeException('Hardware dish image count differs from original table');
$staffName = $lane === 'B' ? 'CDXPARMOB838A9419' : 'CDXPARMOB9411C2CB';
$staffStmt = $db->prepare('SELECT uuid,name,sex,birthday FROM ydy_staff'
    . ' WHERE name=? AND is_show=1');
$staffStmt->execute([$staffName]);
$staffRows = $staffStmt->fetchAll(PDO::FETCH_ASSOC);
if (count($staffRows) !== 1) throw new RuntimeException('Synthetic staff source not unique');
$sourceStaff = array_change_key_case($staffRows[0], CASE_LOWER);
$staffHttp = $http('getStaffByName', 'POST',
    http_build_query(['getStaffByName' => $staffName]), true);
foreach (['uuid', 'name', 'sex', 'birthday'] as $field) {
    if ((string)($staffHttp[$field] ?? '') !== (string)$sourceStaff[$field])
        throw new RuntimeException('Staff-by-name HTTP differs from original row');
}
if (!isset($staffHttp['age']) || !is_numeric($staffHttp['age']))
    throw new RuntimeException('Staff-by-name age contract missing');
$nutritionStationCount = (int)$db->query('SELECT COUNT(*) FROM ydy_nutrition_station')
    ->fetchColumn();
echo json_encode(['lane' => $lane,
    'department_tree_nodes_source_equal' => count($seen),
    'department_active_source_count' => count($sourceDepartments),
    'sport_root_items_source_equal' => count($sports),
    'all_dishes_source_equal' => count($dishes),
    'all_dishes_get_post_equal' => true,
    'hardware_dish_image_source_count' => $sourceHardwareCount,
    'hardware_empty_limited' => $sourceHardwareCount === 0,
    'staff_by_name_original_equal' => true,
    'staff_by_name_types' => array_map('gettype', $staffHttp),
    'nutrition_station_source_count' => $nutritionStationCount,
    'business_http' => 6, 'business_dml' => 0], JSON_UNESCAPED_SLASHES), PHP_EOL;
