<?php
declare(strict_types=1);

// Exactly one isolated Store Agent click, using a unique route/user marker.
// No secrets, tokens, user rows, or raw HTTP payloads are emitted.
$lane = (string)($argv[1] ?? '');
$mode = (string)($argv[2] ?? '');
if (count($argv) !== 3 || !in_array($lane, ['B', 'C'], true)
    || !in_array($mode, ['--preflight', '--run', '--audit'], true)
    || ($mode === '--run' && getenv('CDX_WIDE_CLICK_RUN') !== 'ONE_OWN_CLICK_EXACT_CLEAN_V1')) {
    echo json_encode(['status' => 'default_deny', 'http' => false, 'dml' => false]), PHP_EOL;
    exit(78);
}
$root = $lane === 'B' ? '/tmp/zhct-http-store-mysql.dQTTBP'
    : '/tmp/zhct-dm-poc-20260928.fcpiiN/store';
$pid = $lane === 'B' ? 10001 : 112175;
$port = $lane === 'B' ? 18081 : 18080;
$base = 'http://127.0.0.1:' . $port;
$table = $lane === 'B' ? 'ydy_agent_suggestion_click_log' : 'YDY_AGENT_SUGGESTION_CLICK_LOG';
$marker = 'cdxwideclick20261009d7a42b91';
$high = '9007199254740993';
$stage = 'boundary';
set_exception_handler(static function (Throwable $error) use (&$stage, $lane): void {
    echo json_encode(['status' => 'redacted_stop', 'lane' => $lane, 'stage' => $stage,
        'class' => get_class($error), 'message_sha' => hash('sha256', $error->getMessage())]), PHP_EOL;
    exit(2);
});
if (PHP_VERSION_ID < 70300 || PHP_VERSION_ID >= 70400 || !is_dir($root) || is_link($root)) {
    throw new RuntimeException('PHP or root drift');
}
$cmdline = (string)@file_get_contents('/proc/' . $pid . '/cmdline');
$children = trim((string)@file_get_contents('/proc/' . $pid . '/task/' . $pid . '/children'));
$boundary = json_decode((string)@file_get_contents($base . '/__poc_boundary'), true);
if (strpos($cmdline, '127.0.0.1:' . $port) === false
    || strpos($cmdline, $root . '/public') === false || $children !== ''
    || !is_array($boundary) || ($boundary['external_stubs'] ?? null) !== true
    || ($boundary['redis_isolated'] ?? null) !== true
    || ($boundary['real_queue'] ?? true) !== false) {
    throw new RuntimeException('Isolated HTTP boundary drift');
}
if (hash_file('sha256', $root . '/application/p/controller/Agent.php')
    !== 'a013ffd6ac7f07633a9296b929c21388660abfbb5d43ba7bbe5ae7aa062daa31') {
    throw new RuntimeException('Agent controller drift');
}
$runtime = require $root . '/application/database.php';
if ($lane === 'B') {
    $local = require '/workspace/zhct/zhctproject/store/application/config/local/database.php';
    foreach (['hostname', 'database', 'username', 'password'] as $key) {
        if ((string)($runtime[$key] ?? '') !== (string)($local[$key] ?? '')) {
            throw new RuntimeException('Not code-local MySQL');
        }
    }
    if ((int)($runtime['hostport'] ?? 3306) !== (int)($local['hostport'] ?? 3306)) {
        throw new RuntimeException('MySQL port drift');
    }
    $dsn = 'mysql:host=' . $runtime['hostname'] . ';port=' . $runtime['hostport']
        . ';dbname=' . $runtime['database'] . ';charset=' . ($runtime['charset'] ?? 'utf8');
} else {
    foreach (['hostname' => 'POC_HOST', 'hostport' => 'POC_PORT', 'database' => 'POC_SCHEMA',
        'username' => 'POC_USER', 'password' => 'POC_PASSWORD'] as $key => $envKey) {
        if ((string)($runtime[$key] ?? '') !== (string)getenv($envKey)) {
            throw new RuntimeException('DM worker config drift');
        }
    }
    if ((string)getenv('POC_HOST') !== '127.0.0.1' || (string)getenv('POC_PORT') !== '5237'
        || (string)getenv('POC_SCHEMA') !== 'ZHCT_APP') {
        throw new RuntimeException('Not isolated Store DM');
    }
    $dsn = 'dm:host=127.0.0.1;port=5237;schema=ZHCT_APP';
}
$connect = static function () use ($dsn, $runtime): PDO {
    return new PDO($dsn, (string)$runtime['username'], (string)$runtime['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
            PDO::ATTR_CASE => PDO::CASE_LOWER, PDO::ATTR_TIMEOUT => 5]);
};
$db = $connect();
$identity = $lane === 'B'
    ? (string)$db->query("SELECT CONCAT(@@server_uuid,'|',@@hostname,'|',@@port,'|',DATABASE())")->fetchColumn()
    : 'ZHCT_APP|5237|' . (string)$db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn();
$identitySha = $lane === 'B'
    ? '003eb5aecf1cd4595b609c1f7f20b9ee325b578309fb9fe14fedaf77584fa401'
    : 'bc98485aed26beab348770a82ae38dbf922b04ab88a210cd7282c4caf0156194';
if (hash('sha256', $identity) !== $identitySha) throw new RuntimeException('Database identity drift');
$stage = 'metadata';
$metadata = $db->prepare($lane === 'B'
    ? 'SELECT COLUMN_NAME,DATA_TYPE,COLUMN_TYPE,NUMERIC_PRECISION,NUMERIC_SCALE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME=?'
    : 'SELECT COLUMN_NAME,DATA_TYPE,DATA_TYPE,DATA_PRECISION,DATA_SCALE FROM USER_TAB_COLUMNS WHERE TABLE_NAME=?');
$metadata->execute([$table]);
$meta = [];
foreach ($metadata->fetchAll(PDO::FETCH_NUM) as $row) $meta[strtoupper((string)$row[0])] = $row;
foreach (['ID', 'CONVERSATION_LOG_ID', 'ROUTE', 'USER_UUID', 'CREATE_TIME'] as $column) {
    if (!isset($meta[$column])) throw new RuntimeException('Required column absent');
}
$wide = $meta['CONVERSATION_LOG_ID'];
if ($lane === 'B') {
    if (strtolower((string)$wide[2]) !== 'bigint(20) unsigned') {
        throw new RuntimeException('MySQL wide type drift');
    }
} elseif (strtoupper((string)$wide[1]) !== 'DECIMAL'
    || (int)$wide[3] !== 20 || (int)$wide[4] !== 0) {
    throw new RuntimeException('DM wide type drift');
}
$count = static function (PDO $pdo) use ($table, $marker): int {
    $stmt = $pdo->prepare('SELECT COUNT(*) FROM ' . $table . ' WHERE ROUTE=? OR USER_UUID=?');
    $stmt->execute([$marker, $marker]);
    return (int)$stmt->fetchColumn();
};
$existing = $count($db);
if ($mode !== '--run') {
    echo json_encode(['status' => $existing === 0
        ? ($mode === '--audit' ? 'independent_zero_pass' : 'ready') : 'residue_stop',
        'lane' => $lane, 'marker_rows' => $existing, 'wide_type_ok' => true,
        'http' => false, 'dml' => false]), PHP_EOL;
    exit($existing === 0 ? 0 : 2);
}
if ($existing !== 0) throw new RuntimeException('Marker collision or residue');
$stage = 'http';
$httpStatus = 0;
$httpComplete = false;
$businessSaved = false;
$storedExact = false;
$idMatches = false;
$rows = [];
$failureClass = '';
try {
    require_once $root . '/application/base/Security.php';
    $token = \app\base\Security::encrypt(implode("\t", [
        '0', $marker, $marker, '0', '', '', $marker]));
    if (!is_string($token) || $token === '') throw new RuntimeException('Fixture token unavailable');
    $form = http_build_query(['log_id' => $high, 'suggestion_id' => 1, 'route' => $marker],
        '', '&', PHP_QUERY_RFC3986);
    $context = stream_context_create(['http' => ['method' => 'POST', 'ignore_errors' => true,
        'follow_location' => 0, 'timeout' => 25,
        'header' => "Content-Type: application/x-www-form-urlencoded\r\ntoken: " . $token . "\r\n",
        'content' => $form]]);
    $handle = @fopen($base . '/p/agent/suggestionClick', 'rb', false, $context);
    $raw = is_resource($handle) ? stream_get_contents($handle, 1048577) : false;
    $headers = $http_response_header ?? [];
    $streamMeta = is_resource($handle) ? stream_get_meta_data($handle) : [];
    if (is_resource($handle)) fclose($handle);
    preg_match('~HTTP/\S+\s+(\d+)~', (string)($headers[0] ?? ''), $match);
    $httpStatus = (int)($match[1] ?? 0);
    $httpComplete = is_string($raw) && strlen($raw) <= 1048576 && empty($streamMeta['timed_out']);
    $body = $httpComplete ? json_decode($raw, true) : null;
    $businessSaved = $httpStatus === 200 && is_array($body)
        && (int)($body['code'] ?? -1) === 0 && ($body['data']['saved'] ?? null) === true
        && (int)($body['data']['id'] ?? 0) > 0;
    $stage = 'independent_readback';
    $reader = $connect();
    $sql = $lane === 'B'
        ? 'SELECT ID, CAST(CONVERSATION_LOG_ID AS CHAR(40)) AS EXACT_VALUE FROM ' . $table . ' WHERE ROUTE=? AND USER_UUID=?'
        : 'SELECT ID, CAST(CONVERSATION_LOG_ID AS VARCHAR(40)) AS EXACT_VALUE FROM ' . $table . ' WHERE ROUTE=? AND USER_UUID=?';
    $stmt = $reader->prepare($sql);
    $stmt->execute([$marker, $marker]);
    $rows = $stmt->fetchAll(PDO::FETCH_NUM);
    $storedExact = count($rows) === 1 && (string)$rows[0][1] === $high;
    $idMatches = count($rows) === 1 && (int)$rows[0][0] === (int)($body['data']['id'] ?? 0);
} catch (Throwable $error) {
    $failureClass = get_class($error);
}
$stage = 'exact_cleanup';
$deleted = 0;
$ownerQuery = $connect()->prepare('SELECT ID FROM ' . $table . ' WHERE ROUTE=? AND USER_UUID=?');
$ownerQuery->execute([$marker, $marker]);
$ownedIds = $ownerQuery->fetchAll(PDO::FETCH_COLUMN);
if (count($ownedIds) === 1 && (int)$ownedIds[0] > 0) {
    $cleaner = $connect();
    $remove = $cleaner->prepare('DELETE FROM ' . $table . ' WHERE ID=? AND ROUTE=? AND USER_UUID=?');
    $remove->execute([(int)$ownedIds[0], $marker, $marker]);
    $deleted = $remove->rowCount();
}
$zero = $count($connect()) === 0;
$pass = $failureClass === '' && $httpComplete && $businessSaved
    && $storedExact && $idMatches && $deleted === 1 && $zero;
echo json_encode(['status' => $pass ? 'pass_exact_clean' : 'fail_or_incomplete',
    'lane' => $lane, 'http_status' => $httpStatus, 'http_complete' => $httpComplete,
    'business_saved' => $businessSaved, 'returned_id_matches' => $idMatches,
    'owned_rows_after_http' => count($rows), 'sql_text_exact' => $storedExact,
    'owned_rows_deleted' => $deleted, 'independent_zero' => $zero,
    'failure_class' => $failureClass]), PHP_EOL;
exit($pass ? 0 : 2);
