<?php
declare(strict_types=1);

// A/B isolated local-development MySQL preflight only. No business HTTP or DML.
$stage = 'bootstrap';
set_exception_handler(static function (Throwable $error) use (&$stage): void {
    echo json_encode(['status' => 'redacted-error', 'stage' => $stage,
        'class' => get_class($error), 'code' => (string)$error->getCode()]), PHP_EOL;
    exit(2);
});
set_error_handler(static function (int $severity): bool {
    if (!(error_reporting() & $severity)) return false;
    throw new ErrorException('redacted warning', 0, $severity);
});
$target = (string)getenv('POC_HEALTH_TARGET');
$roots = [
    'A' => ['/private/tmp/zhct-http-ai-macos.zjaU8h', 18105],
    'B' => ['/private/tmp/zhct-http-ai-macos.x2CCZX', 18101],
];
if (!isset($roots[$target])) throw new RuntimeException('Explicit A/B target required');
[$root, $port] = $roots[$target];
$stage = 'local_config_identity';
$path = realpath((string)getenv('POC_MYSQL_LOCAL_ENV'));
if ($path !== '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local') {
    throw new RuntimeException('Approved local development config required');
}
$ini = parse_ini_file($path, true, INI_SCANNER_RAW);
if (!is_array($ini) || !isset($ini['DATABASE'], $ini['DATABASE_ZHCT'])
    || ($ini['DATABASE']['TYPE'] ?? '') !== 'mysql'
    || ($ini['DATABASE_ZHCT']['TYPE'] ?? '') !== 'mysql') {
    throw new RuntimeException('Local MySQL sections unavailable');
}
$config = [];
foreach (['DATABASE' => 'POC_AI_', 'DATABASE_ZHCT' => 'POC_'] as $section => $prefix) {
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT',
        'DATABASE' => 'SCHEMA', 'USERNAME' => 'USER',
        'PASSWORD' => 'PASSWORD'] as $from => $to) {
        $config[$prefix . $to] = (string)($ini[$section][$from] ?? '');
    }
}
$stage = 'isolated_http_process_identity';
$pid = (int)getenv('CDX_HEALTH_HTTP_PID');
$command = $pid > 1 ? shell_exec('/bin/ps eww -p ' . $pid . ' -o command=') : null;
$displayRoot = str_replace('/private/tmp/', '/tmp/', $root);
if (!is_string($command) || $command === ''
    || strpos($command, '-S 127.0.0.1:' . $port) === false
    || (strpos($command, $root . '/public') === false
        && strpos($command, $displayRoot . '/public') === false)) {
    throw new RuntimeException('A/B HTTP test process mismatch');
}
foreach ($config as $key => $value) {
    if ($value === '' || preg_match('/\s/', $value)
        || preg_match('/(?:^|\s)' . preg_quote($key . '=' . $value, '/')
            . '(?=\s|$)/', $command) !== 1) {
        throw new RuntimeException('HTTP runtime differs from local development');
    }
}
$stage = 'external_stub_boundary';
$boundary = json_decode((string)file_get_contents(
    'http://127.0.0.1:' . $port . '/__poc_boundary'), true);
if (!is_array($boundary) || empty($boundary['external_stubs'])
    || !is_file($root . '/vendor/autoload.php')) {
    throw new RuntimeException('Isolated A/B stub/runtime unavailable');
}
$stage = 'development_database_identity';
$connect = static function (string $host, string $port, string $schema,
    string $user, string $password): PDO {
    return new PDO('mysql:host=' . $host . ';port=' . $port
        . ';dbname=' . $schema . ';charset=utf8', $user, $password, [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_CASE => PDO::CASE_LOWER,
            PDO::ATTR_TIMEOUT => 5,
        ]);
};
$ai = $connect($config['POC_AI_HOST'], $config['POC_AI_PORT'],
    $config['POC_AI_SCHEMA'], $config['POC_AI_USER'], $config['POC_AI_PASSWORD']);
$store = $connect($config['POC_HOST'], $config['POC_PORT'],
    $config['POC_SCHEMA'], $config['POC_USER'], $config['POC_PASSWORD']);
if ((string)$ai->query('SELECT DATABASE()')->fetchColumn() !== $config['POC_AI_SCHEMA']
    || (string)$store->query('SELECT DATABASE()')->fetchColumn()
        !== $config['POC_SCHEMA']) {
    throw new RuntimeException('Local double database schema mismatch');
}
$stage = 'required_table_columns';
$aiColumns = [
    'yoshop_user' => 'user_id,store_id,nick_name,is_delete',
    'yoshop_staff' => 'id,user_id,store_id,is_delete,create_time',
    'yoshop_meal' => 'id,staff_id,store_id,meal_date,meal_times,meal_time,'
        . 'create_by,energy,carbohydrate,protein,fat,is_delete',
    'yoshop_meal_infos' => 'id,meal_id,staff_id,store_id,meal_date,meal_times,'
        . 'meal_time,dishes_id,dishes_weight,dishes_number,create_by,is_delete',
    'yoshop_dishes' => 'id,name,weight,energy,is_delete',
];
$storeColumns = [
    'ydy_measurement_session' => 'session_id,ai_user_id,event_type,start_time,'
        . 'end_time,source_platform,vendor,device_type,raw_hash,'
        . 'business_context,is_valid,created_at',
    'ydy_measurement_session_raw' => 'id,session_id',
    'ydy_health_record' => 'record_id,session_id,ai_user_id,metric_code,value,'
        . 'unit,segment,data_source_type,source_platform,start_time,end_time,created_at',
];
$transitive = [
    'yoshop_meal_recommend', 'yoshop_meal_score_subtable',
    'yoshop_dietary_recommend', 'yoshop_dishes_cate',
    'yoshop_dishes_foods', 'yoshop_foods',
    'yoshop_config_enum', 'yoshop_upload_file',
];
foreach ($aiColumns as $table => $columns) {
    $stage = 'ai_columns_' . $table;
    $ai->query('SELECT ' . $columns . ' FROM ' . $table . ' WHERE 1=0');
}
foreach ($transitive as $table) {
    $stage = 'ai_transitive_table_' . $table;
    $ai->query('SELECT 1 FROM ' . $table . ' WHERE 1=0');
}
foreach ($storeColumns as $table => $columns) {
    $stage = 'store_columns_' . $table;
    $store->query('SELECT ' . $columns . ' FROM ' . $table . ' WHERE 1=0');
}
$weekStart = '2027-12-13';
$weekEnd = '2027-12-19';
$count = static function (PDO $pdo, string $sql, array $bind): int {
    $stmt = $pdo->prepare($sql);
    $stmt->execute($bind);
    return (int)$stmt->fetchColumn();
};
$stage = 'candidate_week_aggregate_counts';
$counts = [
    'ai_meal_week' => $count($ai, 'SELECT COUNT(*) FROM yoshop_meal'
        . ' WHERE meal_date>=? AND meal_date<=? AND is_delete=0',
        [$weekStart, $weekEnd]),
    'ai_meal_infos_week' => $count($ai, 'SELECT COUNT(*) FROM yoshop_meal_infos'
        . ' WHERE meal_date>=? AND meal_date<=? AND is_delete=0',
        [$weekStart, $weekEnd]),
    'store_body_scale_week' => $count($store,
        "SELECT COUNT(*) FROM ydy_measurement_session WHERE device_type='body_scale'"
        . ' AND start_time>=? AND start_time<?',
        [$weekStart . ' 00:00:00', '2027-12-20 00:00:00']),
    'positive_mapped_dishes' => $count($ai,
        'SELECT COUNT(*) FROM yoshop_dishes d'
        . ' INNER JOIN yoshop_dishes_foods df ON d.id=df.dishes_id'
        . ' INNER JOIN yoshop_foods f ON f.id=df.foods_id'
        . ' WHERE d.is_delete=0 AND d.weight>0 AND d.energy>0', []),
];
echo json_encode(['status' => 'health-read-ab-readonly-preflight-pass',
    'target' => $target, 'runtime_process_match' => true,
    'local_ai_store_schema_match' => true, 'external_stubs' => true,
    'ai_table_column_groups' => count($aiColumns),
    'ai_transitive_tables' => count($transitive),
    'store_table_column_groups' => count($storeColumns),
    'candidate_week' => [$weekStart, $weekEnd],
    'aggregate_counts_only' => $counts,
    'candidate_week_exclusive' => $counts['ai_meal_week'] === 0
        && $counts['ai_meal_infos_week'] === 0
        && $counts['store_body_scale_week'] === 0,
    'positive_mapped_dish_exists' => $counts['positive_mapped_dishes'] > 0,
    'business_http_count' => 0, 'business_rows_read' => 0, 'writes' => 0],
    JSON_UNESCAPED_SLASHES), PHP_EOL;
