<?php

declare(strict_types=1);

$root = (string)getenv('POC_TARGET_ROOT');
$base = rtrim((string)getenv('POC_BASE_URL'), '/');
$dialect = (string)getenv('POC_DIALECT');
if (!in_array($dialect, ['dm', 'mysql'], true) || strpos($root, '/tmp/zhct-') !== 0
    || !preg_match('~^http://127\.0\.0\.1:[0-9]+$~', $base)
    || !is_file($root . '/vendor/autoload.php')) {
    throw new RuntimeException('Explicit isolated AI metric runtime required');
}
if ($dialect === 'mysql') {
    $path = (string)getenv('POC_MYSQL_LOCAL_ENV');
    $approvedLocal = '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local';
    if (realpath($path) === false || realpath($path) !== realpath($approvedLocal)) {
        throw new RuntimeException('Only code local AI development config allowed');
    }
    $local = parse_ini_file($path, true, INI_SCANNER_RAW);
    if (!is_array($local) || !isset($local['DATABASE'])) {
        throw new RuntimeException('Code local AI main database unavailable');
    }
    foreach (['HOSTNAME' => 'HOST', 'HOSTPORT' => 'PORT', 'DATABASE' => 'SCHEMA',
        'USERNAME' => 'USER', 'PASSWORD' => 'PASSWORD'] as $from => $to) {
        putenv('POC_AI_' . $to . '=' . (string)$local['DATABASE'][$from]);
    }
} else {
    $pid = (string)getenv('POC_RUNTIME_PID');
    if (!ctype_digit($pid) || (int)$pid <= 1) {
        throw new RuntimeException('Approved AI HTTP runtime PID required');
    }
    $processEnv = [];
    foreach (explode("\0", (string)@file_get_contents('/proc/' . $pid . '/environ')) as $entry) {
        $parts = explode('=', $entry, 2);
        if (count($parts) === 2) $processEnv[$parts[0]] = $parts[1];
    }
    if (($processEnv['POC_TARGET_ROOT'] ?? '') !== $root
        || ($processEnv['POC_BASE_URL'] ?? '') !== $base
        || ($processEnv['POC_DIALECT'] ?? '') !== 'dm') {
        throw new RuntimeException('Selected AI HTTP process identity differs');
    }
    foreach (['POC_AI_HOST', 'POC_AI_PORT', 'POC_AI_SCHEMA', 'POC_AI_USER',
        'POC_AI_PASSWORD'] as $name) {
        if (empty($processEnv[$name])) throw new RuntimeException('AI HTTP process database context absent');
        putenv($name . '=' . $processEnv[$name]);
    }
}
foreach (['POC_AI_HOST', 'POC_AI_PORT', 'POC_AI_SCHEMA', 'POC_AI_USER',
    'POC_AI_PASSWORD'] as $name) {
    if ((string)getenv($name) === '') throw new RuntimeException('AI main database config incomplete');
}
if ($dialect === 'dm' && ((string)getenv('POC_AI_PORT') !== '5238'
    || (string)getenv('POC_AI_SCHEMA') !== 'AIZHCT_APP'
    || (string)getenv('POC_AI_USER') !== 'AIZHCT_APP')) {
    throw new RuntimeException('Non-production AI DM schema boundary failed');
}
$boundaryRaw = @file_get_contents($base . '/__poc_boundary', false,
    stream_context_create(['http' => ['timeout' => 5]]));
$boundary = is_string($boundaryRaw) ? json_decode($boundaryRaw, true) : null;
if (!is_array($boundary) || empty($boundary['external_stubs'])) {
    throw new RuntimeException('AI external stubs boundary absent');
}

define('TP_ENV', 'poc');
define('BUSINESS', 'aizhct');
define('ENTERPRISE_NO', '10001');
require $root . '/vendor/autoload.php';
(new \think\App($root))->setEnvName('poc')->initialize();

$dsn = $dialect === 'dm'
    ? 'dm:host=' . getenv('POC_AI_HOST') . ';port=' . getenv('POC_AI_PORT')
        . ';schema=' . getenv('POC_AI_SCHEMA')
    : 'mysql:host=' . getenv('POC_AI_HOST') . ';port=' . getenv('POC_AI_PORT')
        . ';dbname=' . getenv('POC_AI_SCHEMA') . ';charset=utf8mb4';
$db = new PDO($dsn, getenv('POC_AI_USER'), getenv('POC_AI_PASSWORD'),
    [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER,
        PDO::ATTR_TIMEOUT => 5]);
if ($dialect === 'dm') {
    $currentSchema = (string)$db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")
        ->fetchColumn();
    $loginUser = (string)$db->query('SELECT USER FROM DUAL')->fetchColumn();
    if ($currentSchema !== 'AIZHCT_APP' || $loginUser !== 'AIZHCT_APP') {
        throw new RuntimeException('Effective AI DM schema/login user diverged');
    }
}
$table = static function (string $name) use ($dialect): string {
    return $dialect === 'dm' ? strtoupper($name) : $name;
};
$recordTable = $table('yoshop_user_health_metric_record');
$userTable = $table('yoshop_user');
$staffTable = $table('yoshop_staff');
$diseaseTable = $table('yoshop_user_disease');
$workTable = $table('yoshop_health_suggestion_work');
$storeTable = $table('yoshop_store');
$rows = static function (string $sql, array $args = []) use ($db): array {
    $statement = $db->prepare($sql);
    $statement->execute($args);
    return $statement->fetchAll(PDO::FETCH_ASSOC);
};
$one = static function (string $sql, array $args = []) use ($rows): array {
    return $rows($sql, $args)[0] ?? [];
};
$count = static function (string $sql, array $args = []) use ($one): int {
    return (int)($one($sql, $args)['n'] ?? -1);
};
$assert = static function (bool $ok, string $message): void {
    if (!$ok) throw new RuntimeException($message);
};
foreach ([$recordTable, $userTable, $staffTable, $diseaseTable, $workTable, $storeTable] as $required) {
    $db->query('SELECT 1 FROM ' . $required . ' WHERE 1=0');
}
$assert($count('SELECT COUNT(*) N FROM ' . $storeTable
    . ' WHERE STORE_ID=? AND IS_DELETE=0', [10001]) === 1,
    'Approved AI store row absent/ambiguous');
if ((string)getenv('POC_PREFLIGHT_ONLY') === '1') {
    if ($dialect === 'dm') {
        $current = (string)$db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn();
        $assert($current === 'AIZHCT_APP', 'Effective AI DM schema diverged');
    }
    echo json_encode(['suite' => 'health-metric-' . $dialect,
        'mode' => 'read-only-preflight', 'required_tables_present' => true,
        'marker_record_rows' => $count('SELECT COUNT(*) N FROM ' . $recordTable
            . ' WHERE SOURCE_KEY LIKE ?', ['CDXPARMETRIC%']),
        'marker_user_rows' => $count('SELECT COUNT(*) N FROM ' . $userTable
            . ' WHERE NICK_NAME LIKE ?', ['CDXPARMETRIC%'])], JSON_UNESCAPED_SLASHES) . PHP_EOL;
    exit(0);
}

$marker = 'CDXPARMETRIC' . strtoupper(bin2hex(random_bytes(4)));
$requestId = $marker . 'REQ';
$badRequestId = $marker . 'BAD';
$token = $marker . 'TOKEN' . strtoupper(bin2hex(random_bytes(10)));
$today = date('Y-m-d');
$start = date('Y-m-d', strtotime('-7 days'));
$userId = 0;
$recordId = 0;
$results = [];
$cleanup = [];
$failure = '';
$ownedSourceKeys = [$requestId => 'glucose', $badRequestId => ['glucose', 'INVALID']];
$request = static function (string $method, string $action, ?string $auth,
    array $params = []) use ($base): array {
    $headers = "platform: POC\r\nContent-Type: application/x-www-form-urlencoded\r\n";
    if ($auth !== null) $headers .= 'Access-Token: ' . $auth . "\r\n";
    $query = $method === 'GET' ? '?' . http_build_query($params + ['storeId' => 10001])
        : '?storeId=10001';
    $body = $method === 'POST' ? http_build_query(['form' => $params]) : '';
    $context = stream_context_create(['http' => ['method' => $method,
        'header' => $headers, 'content' => $body, 'timeout' => 30,
        'ignore_errors' => true]]);
    $raw = @file_get_contents($base . '/api/health.metric/' . $action . $query, false, $context);
    $headerOut = $http_response_header ?? [];
    preg_match('/HTTP\/\S+\s+(\d+)/', (string)($headerOut[0] ?? ''), $match);
    $json = is_string($raw) ? json_decode($raw, true) : null;
    return ['http' => isset($match[1]) ? (int)$match[1] : 0,
        'status' => is_array($json) ? (int)($json['status'] ?? -1) : -1,
        'message' => is_array($json) ? (string)($json['message'] ?? '') : '',
        'data' => is_array($json) ? ($json['data'] ?? null) : null];
};
$success = static function (array $response): bool {
    return $response['http'] === 200 && $response['status'] === 200
        && is_array($response['data']);
};
$metricFromOverview = static function (array $data): ?array {
    foreach (($data['groups'] ?? []) as $group) {
        foreach (($group['metrics'] ?? []) as $metric) {
            if (is_array($metric) && ($metric['metric_code'] ?? '') === 'glucose') return $metric;
        }
    }
    return null;
};
$record = static function () use ($one, $recordTable, &$userId, $requestId): array {
    if ($userId <= 0) return [];
    return $one('SELECT ID,USER_ID,STORE_ID,METRIC_CODE,VALUE,MEASURE_DATE,MEASURE_TIME,'
        . ' SOURCE_TYPE,SOURCE_KEY,IS_DELETE,EVALUATION_CODE FROM ' . $recordTable
        . ' WHERE USER_ID=? AND SOURCE_KEY=? AND METRIC_CODE=?',
        [$userId, $requestId, 'glucose']);
};
$recordCount = static function () use ($count, $recordTable, &$userId): int {
    return $userId > 0 ? $count('SELECT COUNT(*) N FROM ' . $recordTable
        . ' WHERE USER_ID=?', [$userId]) : 0;
};
$relatedZero = static function () use ($count, $staffTable, $diseaseTable,
    $workTable, &$userId): bool {
    if ($userId <= 0) return true;
    return $count('SELECT COUNT(*) N FROM ' . $staffTable . ' WHERE USER_ID=?', [$userId]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $diseaseTable . ' WHERE USER_ID=?', [$userId]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $workTable
            . ' WHERE STAFF_ID IN (SELECT ID FROM ' . $staffTable . ' WHERE USER_ID=?)', [$userId]) === 0;
};
try {
    $assert($count('SELECT COUNT(*) N FROM ' . $userTable
        . ' WHERE NICK_NAME=?', [$marker]) === 0
        && $count('SELECT COUNT(*) N FROM ' . $recordTable
            . ' WHERE SOURCE_KEY IN (?,?)', [$requestId, $badRequestId]) === 0,
        'Synthetic health metric marker already exists');
    $results['marker_before_zero'] = true;
    $db->prepare('INSERT INTO ' . $userTable
        . ' (STORE_ID,MOBILE,NICK_NAME,BALANCE,GIFT_BALANCE,IS_DELETE,CREATE_TIME)'
        . ' VALUES (10001,?,?,?,?,0,?)')
        ->execute(['', $marker, '0.00', '0.00', time()]);
    $userId = (int)($one('SELECT USER_ID FROM ' . $userTable
        . ' WHERE NICK_NAME=?', [$marker])['user_id'] ?? 0);
    $assert($userId > 0 && $relatedZero() && $recordCount() === 0,
        'Synthetic AI user or zero-related-row gate failed');
    \think\facade\Cache::set($token, ['user' => ['user_id' => $userId],
        'password_version' => 0, 'login_type' => 'thirdparty'], 300);

    $form = ['request_id' => $requestId, 'metric_code' => 'glucose',
        'measure_date' => $today, 'measure_time' => '09:30', 'value' => '5.5'];
    $unauth = $request('POST', 'create', null, $form);
    $assert($unauth['status'] === 401 && $recordCount() === 0,
        'Unauthenticated metric create wrote or route failed');
    $results['unauth_create_rejected_zero_write'] = true;

    $empty = $request('GET', 'overview', $token);
    $emptyMetric = is_array($empty['data']) ? $metricFromOverview($empty['data']) : null;
    $assert($success($empty) && is_array($emptyMetric)
        && ($emptyMetric['has_record'] ?? null) === false && $recordCount() === 0,
        'Empty metric overview contract failed');
    $results['overview_empty_authenticated_shape'] = true;

    $invalidCode = $request('POST', 'create', $token,
        array_replace($form, ['metric_code' => 'INVALID', 'request_id' => $badRequestId]));
    $invalidDate = $request('POST', 'create', $token,
        array_replace($form, ['measure_date' => '2099-01-01', 'request_id' => $badRequestId]));
    $assert($invalidCode['status'] !== 200 && $invalidDate['status'] !== 200
        && $recordCount() === 0 && $relatedZero(),
        'Invalid metric/date was accepted or wrote rows');
    $results['invalid_inputs_zero_write'] = true;

    $created = $request('POST', 'create', $token, $form);
    $source = $record();
    $recordId = (int)($source['id'] ?? 0);
    $createdData = $created['data'];
    $assert($success($created) && is_array($createdData)
        && $recordId > 0 && $recordCount() === 1
        && (int)($source['user_id'] ?? 0) === $userId
        && (int)($source['store_id'] ?? 0) === 10001
        && (int)($source['source_type'] ?? 0) === 1
        && (int)($source['is_delete'] ?? -1) === 0
        && abs((float)($source['value'] ?? 0) - 5.5) < 0.00001
        && substr((string)($source['measure_date'] ?? ''), 0, 10) === $today
        && substr((string)($source['measure_time'] ?? ''), 0, 5) === '09:30'
        && (int)($createdData['id'] ?? 0) === $recordId
        && ($createdData['value'] ?? null) === 5.5
        && ($createdData['display_value'] ?? null) === '5.5'
        && $relatedZero(), 'Metric create HTTP/source contract failed');
    $results['create_one_decimal_date_time_and_response'] = true;

    $repeat = $request('POST', 'create', $token, $form);
    $assert($success($repeat) && (int)($repeat['data']['id'] ?? 0) === $recordId
        && $recordCount() === 1 && $relatedZero(),
        'Metric same request_id was not idempotent');
    $results['repeat_same_request_id_one_row'] = true;

    $overview = $request('GET', 'overview', $token);
    $metric = is_array($overview['data']) ? $metricFromOverview($overview['data']) : null;
    $assert($success($overview) && is_array($metric)
        && ($metric['has_record'] ?? null) === true
        && ($metric['value'] ?? null) === 5.5
        && ($metric['display_value'] ?? null) === '5.5',
        'Metric overview did not reflect source row');
    $results['overview_nonempty_source_match'] = true;

    $range = ['metric_code' => 'glucose', 'start_date' => $start, 'end_date' => $today];
    $trend = $request('GET', 'trend', $token, $range);
    $trendData = $trend['data'];
    $assert($success($trend) && is_array($trendData)
        && (int)($trendData['total'] ?? -1) === 1
        && count((array)($trendData['records'] ?? [])) === 1
        && count((array)($trendData['recent_records'] ?? [])) === 1
        && (int)($trendData['latest']['id'] ?? 0) === $recordId
        && ($trendData['latest']['value'] ?? null) === 5.5
        && ($trendData['latest']['time'] ?? null) === '09:30',
        'Metric trend nonempty source contract failed');
    $results['trend_nonempty_one_latest'] = true;

    $page1 = $request('GET', 'records', $token,
        $range + ['page' => 1, 'page_size' => 1]);
    $page2 = $request('GET', 'records', $token,
        $range + ['page' => 2, 'page_size' => 1]);
    $a = $page1['data'];
    $b = $page2['data'];
    $assert($success($page1) && $success($page2)
        && (int)($a['total'] ?? -1) === 1
        && (int)($a['current_page'] ?? 0) === 1
        && (int)($a['per_page'] ?? 0) === 1
        && ($a['has_more'] ?? null) === false
        && count((array)($a['list'] ?? [])) === 1
        && (int)($a['list'][0]['id'] ?? 0) === $recordId
        && (int)($b['total'] ?? -1) === 1
        && count((array)($b['list'] ?? [])) === 0,
        'Metric records pagination/source contract failed');
    $results['records_page1_page2_total'] = true;
    $results['json_types'] = [
        'id' => gettype($createdData['id'] ?? null),
        'value' => gettype($createdData['value'] ?? null),
        'display_value' => gettype($createdData['display_value'] ?? null),
        'measure_date' => gettype($createdData['measure_date'] ?? null),
        'measure_time' => gettype($createdData['measure_time'] ?? null),
        'has_more' => gettype($a['has_more'] ?? null),
        'total' => gettype($a['total'] ?? null),
    ];

    if ((string)getenv('POC_METRIC_BOUNDARIES') === '1') {
        $bloodPressureCases = [
            ['date' => date('Y-m-d', strtotime('-2 days')), 'time' => '08:10',
                'value' => '60', 'secondary' => '40', 'evaluation' => 'normal'],
            ['date' => date('Y-m-d', strtotime('-1 day')), 'time' => '09:20',
                'value' => '120', 'secondary' => '80', 'evaluation' => 'elevated'],
            ['date' => $today, 'time' => '10:30',
                'value' => '240', 'secondary' => '160', 'evaluation' => 'high'],
        ];
        $bloodPressureIds = [];
        foreach ($bloodPressureCases as $index => $case) {
            $key = $marker . 'BP' . ($index + 1);
            $ownedSourceKeys[$key] = 'blood_pressure';
            $payload = ['request_id' => $key, 'metric_code' => 'blood_pressure',
                'measure_date' => $case['date'], 'measure_time' => $case['time'],
                'value' => $case['value'], 'secondary_value' => $case['secondary']];
            $response = $request('POST', 'create', $token, $payload);
            $stored = $one('SELECT ID,VALUE,SECONDARY_VALUE,MEASURE_DATE,MEASURE_TIME,'
                . ' EVALUATION_CODE,SOURCE_TYPE,IS_DELETE FROM ' . $recordTable
                . ' WHERE USER_ID=? AND SOURCE_KEY=? AND METRIC_CODE=?',
                [$userId, $key, 'blood_pressure']);
            $bloodPressureIds[] = (int)($stored['id'] ?? 0);
            $assert($success($response) && (int)($stored['id'] ?? 0) > 0
                && (int)($stored['source_type'] ?? 0) === 1
                && (int)($stored['is_delete'] ?? -1) === 0
                && abs((float)($stored['value'] ?? 0) - (float)$case['value']) < 0.00001
                && abs((float)($stored['secondary_value'] ?? 0) - (float)$case['secondary']) < 0.00001
                && substr((string)($stored['measure_date'] ?? ''), 0, 10) === $case['date']
                && substr((string)($stored['measure_time'] ?? ''), 0, 5) === $case['time']
                && (string)($stored['evaluation_code'] ?? '') === $case['evaluation']
                && (int)($response['data']['id'] ?? 0) === (int)$stored['id']
                && (float)($response['data']['value'] ?? 0) === (float)$case['value']
                && (float)($response['data']['secondary_value'] ?? 0) === (float)$case['secondary']
                && (string)($response['data']['evaluation']['code'] ?? '') === $case['evaluation']
                && $relatedZero(), 'Blood pressure HTTP/source boundary case failed');
        }
        $assert(count(array_unique($bloodPressureIds)) === 3 && $recordCount() === 4,
            'Blood pressure three-day source row count failed');
        $results['blood_pressure_lower_threshold_upper_three_rows'] = true;

        $bpRange = ['metric_code' => 'blood_pressure',
            'start_date' => $bloodPressureCases[0]['date'], 'end_date' => $today];
        $bpTrend = $request('GET', 'trend', $token, $bpRange);
        $trendRows = $bpTrend['data']['records'] ?? null;
        $assert($success($bpTrend) && (int)($bpTrend['data']['total'] ?? -1) === 3
            && is_array($trendRows) && count($trendRows) === 3
            && array_column($trendRows, 'measure_date') === array_column($bloodPressureCases, 'date')
            && array_column($trendRows, 'id') === $bloodPressureIds
            && (int)($bpTrend['data']['latest']['id'] ?? 0) === $bloodPressureIds[2]
            && (float)($bpTrend['data']['latest']['systolic'] ?? 0) === 240.0
            && (float)($bpTrend['data']['latest']['diastolic'] ?? 0) === 160.0
            && count((array)($bpTrend['data']['recent_records'] ?? [])) === 3,
            'Blood pressure three-day trend/ordering contract failed');
        $results['blood_pressure_trend_three_day_order_latest'] = true;

        $bpPage1 = $request('GET', 'records', $token, $bpRange + ['page' => 1, 'page_size' => 2]);
        $bpPage2 = $request('GET', 'records', $token, $bpRange + ['page' => 2, 'page_size' => 2]);
        $assert($success($bpPage1) && $success($bpPage2)
            && (int)($bpPage1['data']['total'] ?? -1) === 3
            && count((array)($bpPage1['data']['list'] ?? [])) === 2
            && ($bpPage1['data']['has_more'] ?? null) === true
            && (int)($bpPage1['data']['list'][0]['id'] ?? 0) === $bloodPressureIds[2]
            && (int)($bpPage2['data']['total'] ?? -1) === 3
            && count((array)($bpPage2['data']['list'] ?? [])) === 1
            && ($bpPage2['data']['has_more'] ?? null) === false
            && (int)($bpPage2['data']['list'][0]['id'] ?? 0) === $bloodPressureIds[0],
            'Blood pressure two-page history contract failed');
        $results['blood_pressure_records_two_page_descending'] = true;

        $bpOverview = $request('GET', 'overview', $token);
        $bpMetric = null;
        foreach (($bpOverview['data']['groups'] ?? []) as $group) {
            foreach (($group['metrics'] ?? []) as $item) {
                if (($item['metric_code'] ?? '') === 'blood_pressure') $bpMetric = $item;
            }
        }
        $assert($success($bpOverview) && is_array($bpMetric)
            && ($bpMetric['has_record'] ?? null) === true
            && (float)($bpMetric['value'] ?? 0) === 240.0
            && (float)($bpMetric['secondary_value'] ?? 0) === 160.0
            && ($bpMetric['display_value'] ?? null) === '240/160',
            'Blood pressure overview latest two-value contract failed');
        $results['blood_pressure_overview_latest_two_values'] = true;

        $invalidBloodPressure = [
            ['value' => '59', 'secondary_value' => '40'],
            ['value' => '241', 'secondary_value' => '80'],
            ['value' => '120', 'secondary_value' => '39'],
            ['value' => '120', 'secondary_value' => '161'],
            ['value' => '80', 'secondary_value' => '80'],
            ['value' => '120.123', 'secondary_value' => '80'],
            ['value' => '120'],
            ['value' => '120', 'secondary_value' => '80', 'measure_date' => '2026-02-30'],
        ];
        foreach ($invalidBloodPressure as $index => $changes) {
            $key = $marker . 'BPBAD' . ($index + 1);
            $ownedSourceKeys[$key] = 'blood_pressure';
            $invalidPayload = array_replace([
                'request_id' => $key, 'metric_code' => 'blood_pressure',
                'measure_date' => $today, 'measure_time' => '11:00',
                'value' => '120', 'secondary_value' => '80',
            ], $changes);
            if (!array_key_exists('secondary_value', $changes) && $index === 6) {
                unset($invalidPayload['secondary_value']);
            }
            $invalidResponse = $request('POST', 'create', $token, $invalidPayload);
            $assert($invalidResponse['status'] !== 200 && $recordCount() === 4
                && $relatedZero(), 'Invalid blood pressure boundary accepted or wrote');
        }
        $results['blood_pressure_eight_invalid_inputs_zero_write'] = true;
        $results['blood_pressure_json_types'] = [
            'value' => gettype($bpTrend['data']['latest']['value'] ?? null),
            'secondary_value' => gettype($bpTrend['data']['latest']['secondary_value'] ?? null),
            'display_value' => gettype($bpTrend['data']['latest']['display_value'] ?? null),
            'date' => gettype($bpTrend['data']['latest']['measure_date'] ?? null),
            'time' => gettype($bpTrend['data']['latest']['measure_time'] ?? null),
            'has_more' => gettype($bpPage1['data']['has_more'] ?? null),
        ];
    }
} catch (Throwable $e) {
    $failure = get_class($e) . ':' . hash('sha256', $e->getMessage());
} finally {
    try {
        \think\facade\Cache::delete($token);
        if ($userId > 0) {
            $owned = $rows('SELECT ID,SOURCE_KEY,METRIC_CODE FROM ' . $recordTable
                . ' WHERE USER_ID=?', [$userId]);
            foreach ($owned as $row) {
                $expectedMetric = $ownedSourceKeys[(string)$row['source_key']] ?? null;
                $actualMetric = (string)$row['metric_code'];
                $allowedMetric = is_array($expectedMetric)
                    ? in_array($actualMetric, $expectedMetric, true)
                    : $actualMetric === $expectedMetric;
                if ($expectedMetric === null || !$allowedMetric) {
                    throw new RuntimeException('Unexpected metric for synthetic user; refusing cleanup');
                }
            }
            foreach ($owned as $row) {
                $db->prepare('DELETE FROM ' . $recordTable
                    . ' WHERE ID=? AND USER_ID=? AND SOURCE_KEY=? AND METRIC_CODE=?')
                    ->execute([(int)$row['id'], $userId, (string)$row['source_key'],
                        (string)$row['metric_code']]);
            }
            if (!$relatedZero()) throw new RuntimeException('Synthetic user gained staff/disease/work rows');
            $db->prepare('DELETE FROM ' . $userTable . ' WHERE USER_ID=? AND NICK_NAME=?')
                ->execute([$userId, $marker]);
        }
        $cleanup = [
            'metric_zero' => $userId > 0
                ? $count('SELECT COUNT(*) N FROM ' . $recordTable . ' WHERE USER_ID=?', [$userId]) === 0
                : $count('SELECT COUNT(*) N FROM ' . $recordTable
                    . ' WHERE SOURCE_KEY LIKE ?', [$marker . '%']) === 0,
            'user_zero' => $count('SELECT COUNT(*) N FROM ' . $userTable
                . ' WHERE NICK_NAME=?', [$marker]) === 0,
            'related_zero' => $relatedZero(),
        ];
    } catch (Throwable $e) {
        $cleanup['error_class'] = get_class($e);
        $cleanup['error_sha256'] = hash('sha256', $e->getMessage());
    }
}
$clean = ($cleanup['metric_zero'] ?? false) && ($cleanup['user_zero'] ?? false)
    && ($cleanup['related_zero'] ?? false);
echo json_encode(['suite' => 'health-metric-' . $dialect,
    'marker' => $marker, 'results' => $results,
    'failure' => $failure, 'cleanup' => $cleanup],
    JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
if ($failure !== '' || !$clean) exit(1);
