<?php
declare(strict_types=1);

// New-process read-only verification after one exact chat-write fixture cleanup.
set_exception_handler(static function (Throwable $error): void {
    echo json_encode(['status' => 'zero-check-error', 'class' => get_class($error),
        'code' => (string)$error->getCode()], JSON_UNESCAPED_SLASHES), PHP_EOL;
    exit(2);
});
$lane = (string)getenv('CDX_CHAT_LANE');
$action = (string)getenv('CDX_CHAT_ACTION');
$marker = (string)getenv('CDX_CHAT_MARKER');
if (!in_array($lane, ['A', 'B', 'C'], true)
    || !in_array($action, ['deleteSession', 'clearSession'], true)
    || !preg_match('/^guest_cdx[a-f0-9]{16}$/', $marker)) {
    throw new RuntimeException('Exact target missing');
}
$suffix = substr($marker, strlen('guest_cdx'));
$botId = 'cdxchatbot';
$conversationId = 'cdxchat_' . $suffix;
$journalDir = '/tmp/zhct-ai-chat-write-fixtures-' . $lane . '-' . $action;
$journal = $journalDir . '/' . $suffix . '.json';
if (is_link($journalDir) || !is_dir($journalDir)
    || fileowner($journalDir) !== posix_geteuid()
    || (fileperms($journalDir) & 0777) !== 0700
    || is_link($journal) || !is_file($journal)
    || fileowner($journal) !== posix_geteuid()
    || (fileperms($journal) & 0777) !== 0600) {
    throw new RuntimeException('Private journal missing or unsafe');
}
$record = json_decode((string)file_get_contents($journal), true);
if (!is_array($record) || ($record['lane'] ?? null) !== $lane
    || ($record['action'] ?? null) !== $action
    || ($record['marker'] ?? null) !== $marker
    || ($record['bot_id'] ?? null) !== $botId
    || ($record['conversation_id'] ?? null) !== $conversationId
    || (int)($record['session_id'] ?? 0) < 1
    || (int)($record['message_id'] ?? 0) < 1) {
    throw new RuntimeException('Journal does not identify these two owned rows');
}
if ($lane === 'C') {
    $raw = file_get_contents('/proc/53772/environ');
    $cmd = file_get_contents('/proc/53772/cmdline');
    if ($raw === false || $cmd === false || strpos($cmd, '127.0.0.1:18102') === false
        || strpos($cmd, '/tmp/zhct-ai-http-20260929.3XDj3w/public') === false) {
        throw new RuntimeException('C isolated service changed');
    }
    $env = [];
    foreach (explode("\0", $raw) as $part) {
        if (strpos($part, 'POC_') !== 0) continue;
        $at = strpos($part, '=');
        if ($at !== false) $env[substr($part, 0, $at)] = substr($part, $at + 1);
    }
    if (($env['POC_DIALECT'] ?? '') !== 'dm'
        || ($env['POC_AI_HOST'] ?? '') !== '127.0.0.1'
        || ($env['POC_AI_PORT'] ?? '') !== '5238'
        || ($env['POC_AI_SCHEMA'] ?? '') !== 'AIZHCT_APP') {
        throw new RuntimeException('C AI target changed');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5238;schema=AIZHCT_APP',
        $env['POC_AI_USER'], $env['POC_AI_PASSWORD'], [
            PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    $owner = strtoupper((string)$db->query('SELECT USER FROM DUAL')->fetchColumn());
    $schema = strtoupper((string)$db->query(
        "SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn());
    $fingerprint = hash('sha256', $owner . '|5238|' . $schema);
    $expected = '628c12663da929e593de74c9c58e5bcfab0530fbfbcb1d90a9ed7b736a45fd5e';
} else {
    $path = realpath((string)getenv('POC_MYSQL_LOCAL_ENV'));
    if ($path !== '/Users/wiscourper/Documents/workspace/zhct/zhctproject/ai_api/.env.local') {
        throw new RuntimeException('Wrong local dev config');
    }
    $config = parse_ini_file($path, true, INI_SCANNER_RAW);
    $main = $config['DATABASE'] ?? [];
    $db = new PDO('mysql:host=' . $main['HOSTNAME'] . ';port=' . $main['HOSTPORT']
        . ';dbname=' . $main['DATABASE'] . ';charset=' . ($main['CHARSET'] ?? 'utf8'),
        $main['USERNAME'], $main['PASSWORD'], [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
    $identity = (string)$db->query(
        "SELECT CONCAT(@@server_uuid,'|',@@hostname,'|',@@port,'|',DATABASE())"
    )->fetchColumn();
    $fingerprint = hash('sha256', $identity);
    $expected = '210f925e093f71e26a8c8923f0f626e3be0a15ccff3d386bba21feef695c8a5b';
}
if ($fingerprint !== $expected
    || ($record['database_fingerprint'] ?? null) !== $fingerprint) {
    throw new RuntimeException('Approved AI database/journal mismatch');
}
$s = $db->prepare('SELECT COUNT(*) FROM yoshop_ai_conversation_session '
    . 'WHERE store_id=10001 AND user_id=0 AND ai_user_id=? AND bot_id=? AND conversation_id=?');
$m = $db->prepare('SELECT COUNT(*) FROM yoshop_ai_conversation '
    . 'WHERE store_id=10001 AND user_id=? AND bot_id=? AND conversation_id=?');
$s->execute([$marker, $botId, $conversationId]);
$m->execute([$marker, $botId, $conversationId]);
$counts = [(int)$s->fetchColumn(), (int)$m->fetchColumn()];
$pass = $counts === [0, 0] && ($record['phase'] ?? '') === 'cleaned';
echo json_encode(['status' => $pass ? 'independent-zero' : 'cleanup-unverified',
    'lane' => $lane, 'action' => $action, 'marker' => $marker,
    'counts' => $counts, 'journal_phase' => $record['phase'] ?? null,
    'database_fingerprint' => $fingerprint], JSON_UNESCAPED_SLASHES), PHP_EOL;
exit($pass ? 0 : 3);
