<?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;
    $restaurantId = 25;
} 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 Store 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;
    $restaurantId = 1;
}
$date = '2026-10-09';
$mealTimes = 1;
$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));
};
$recipes = $source('SELECT r.dishes_uuid,d.name,d.weight FROM ydy_recipes r'
    . ' JOIN ydy_dishes d ON r.dishes_uuid=d.uuid'
    . ' WHERE r.restaurant_id=? AND r.menu_date=? AND r.meal_times=? AND d.is_del=1',
    [$restaurantId, $date, $mealTimes]);
if (!$recipes) throw new RuntimeException('no original positive breakfast recipes');
$dishMap = [];
foreach ($recipes as $row) $dishMap[(string)$row['dishes_uuid']] = $row;
$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' => 18, '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('meal HTTP response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('meal HTTP business failure at ' . $path
            . ' code=' . (string)($body['code'] ?? 'nonjson')
            . ' message=' . substr((string)($body['message'] ?? ''), 0, 100));
    }
    return $body;
};
$meal = $http('/p/api/getMeal', ['restaurant_id' => $restaurantId,
    'meal_date' => $date, 'meal_times' => $mealTimes])['data'] ?? null;
if (!is_array($meal) || !$meal) throw new RuntimeException('meal HTTP rows empty');
$matched = 0;
$first = null;
foreach ($meal as $item) {
    if (!is_array($item)) throw new RuntimeException('meal item shape invalid');
    $uuid = (string)($item['uuid'] ?? '');
    if (!isset($dishMap[$uuid])
        || (string)($item['name'] ?? '') !== (string)$dishMap[$uuid]['name']
        || !is_numeric($item['weight'] ?? null)
        || abs((float)$item['weight'] - (float)$dishMap[$uuid]['weight']) > 0.00001) {
        throw new RuntimeException('meal dish differs from original recipes/dishes');
    }
    if ($first === null) $first = $item;
    $matched++;
}
$restaurant = $source('SELECT morning_start,morning_end,noon_start,noon_end'
    . ' FROM ydy_restaurants WHERE id=1');
if (count($restaurant) !== 1) throw new RuntimeException('restaurant-one source absent');
$clock = date('H:i:s');
$times = $restaurant[0];
$expected = $clock > substr((string)$times['morning_start'], 0, 8)
    && $clock <= substr((string)$times['morning_end'], 0, 8) ? 1
    : ($clock > substr((string)$times['noon_start'], 0, 8)
        && $clock < substr((string)$times['noon_end'], 0, 8) ? 2 : 3);
$current = $http('/p/api/getMealTimes', ['restaurant_id' => 1])['data'] ?? null;
if ((int)$current !== $expected || !is_int($current)) {
    throw new RuntimeException('current meal time differs from own restaurant window');
}
if ($recipes !== $source('SELECT r.dishes_uuid,d.name,d.weight FROM ydy_recipes r'
    . ' JOIN ydy_dishes d ON r.dishes_uuid=d.uuid'
    . ' WHERE r.restaurant_id=? AND r.menu_date=? AND r.meal_times=? AND d.is_del=1',
    [$restaurantId, $date, $mealTimes])) {
    throw new RuntimeException('original recipes/dishes source changed during read');
}
$types = [];
foreach ($first as $field => $value) $types[$field] = gettype($value);
ksort($types);
$jsonTypes = array_map(static function (string $type): string {
    return in_array($type, ['integer', 'double'], true) ? 'number' : $type;
}, $types);
echo json_encode(['lane' => $lane, 'http_business_ok' => 2,
    'source_recipe_rows' => count($recipes), 'meal_returned_rows' => $matched,
    'restaurant_time_source_equal' => true,
    'meal_first_row_type_sha256' => hash('sha256', json_encode($types)),
    'meal_first_row_json_type_sha256' => hash('sha256', json_encode($jsonTypes)),
    'business_dml' => 0], JSON_UNESCAPED_SLASHES), PHP_EOL;
