<?php

declare(strict_types=1);

$lane = $argv[1] ?? '';
if (!in_array($lane, ['B', 'C'], true)) exit(2);
$root = '/tmp/cdx-prepay-code-scan-20261012-' . $lane . '-store';
$marker = $lane === 'B' ? 'CDXPPREF12B01-O1' : 'CDXPPREF12C01-O1';
$prepayId = $lane === 'B' ? 26 : 5;
$mealId = $lane === 'B' ? 68503 : 23666;
$aiUserId = $lane === 'B' ? 46921 : 1936;
$dialect = $lane === 'B' ? 'mysql' : 'dm';
$pid = (int)file_get_contents($root . '/private-http.pid');
if (strpos((string)file_get_contents('/proc/' . $pid . '/cmdline'), $root . '/public') === false) {
    throw new RuntimeException('Wrong private Store process');
}
foreach (explode("\0", (string)file_get_contents('/proc/' . $pid . '/environ')) as $pair) {
    $parts = explode('=', $pair, 2);
    if (count($parts) === 2 && strpos($parts[0], 'POC_') === 0) putenv($pair);
}
if (getenv('POC_DIALECT') !== $dialect) throw new RuntimeException('Wrong dialect');
$cfg = require $root . '/application/database.php';
$connect = static function (array $c) use ($dialect): PDO {
    $dsn = $dialect === 'dm'
        ? 'dm:host=' . $c['hostname'] . ';port=' . $c['hostport'] . ';schema=' . $c['database']
        : 'mysql:host=' . $c['hostname'] . ';port=' . ($c['hostport'] ?? 3306)
            . ';dbname=' . $c['database'] . ';charset=utf8mb4';
    return new PDO($dsn, $c['username'], $c['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
};
$store = $connect($cfg);
$ai = $connect($cfg['ai_zhct']);
$table = static function (string $name, bool $isAi = false) use ($dialect): string {
    $prefix = $isAi ? 'yoshop_' : 'ydy_';
    return $dialect === 'dm' ? strtoupper($prefix . $name) : $prefix . $name;
};
$one = static function (PDO $db, string $sql, array $params = []): array {
    $stmt = $db->prepare($sql);
    $stmt->execute($params);
    return array_change_key_case($stmt->fetch(PDO::FETCH_ASSOC) ?: [], CASE_LOWER);
};
$snapshot = static function () use ($one, $store, $ai, $table, $prepayId,
    $mealId, $aiUserId): array {
    $prepay = $one($store, 'SELECT ID,DEVICE_ORDER_NO,MACHID,MEAL_ORDER_ID,USER_ID,'
        . 'PREPAY_STATUS,SHIP_STATUS,ERRINFO,RAW_REQUEST_B FROM '
        . $table('prepay_order') . ' WHERE ID=?', [$prepayId]);
    $meal = $one($store, 'SELECT ID,ORDER_NO,PAY_STATUS,ORDER_STATUS,REFUND_STATUS,'
        . 'REFUND_AMOUNT FROM ' . $table('meal_order') . ' WHERE ID=?', [$mealId]);
    $wallet = $one($ai, 'SELECT BALANCE,SUBSIDY_BALANCE,GIFT_BALANCE FROM '
        . $table('user', true) . ' WHERE USER_ID=?', [$aiUserId]);
    $settlement = $one($ai, 'SELECT COUNT(*) AS N FROM '
        . $table('account_settlement', true) . ' WHERE BIZ_ORDER_NO=?',
        [(string)($meal['order_no'] ?? '')]);
    return compact('prepay', 'meal', 'wallet', 'settlement');
};
$before = $snapshot();
if ((int)($before['prepay']['id'] ?? 0) !== $prepayId
    || (string)$before['prepay']['device_order_no'] !== $marker
    || (int)$before['prepay']['meal_order_id'] !== $mealId
    || (int)$before['prepay']['prepay_status'] !== 1
    || (int)$before['meal']['pay_status'] !== 20
    || (int)$before['meal']['refund_status'] !== 3
    || bccomp((string)$before['wallet']['balance'], '0.05', 2) !== 0
    || (int)$before['settlement']['n'] !== 2) {
    throw new RuntimeException('Only owned paid/refunded prepay may test bad signature');
}
if (getenv('POC_DRY_RUN') === '1') {
    echo json_encode(['lane' => $lane, 'owned_prepay' => $prepayId,
        'negative_sign_only' => true, 'HTTP' => 0, 'DML' => 0]) . PHP_EOL;
    exit(0);
}
$attemptPath = $root . '/fulfill-bad-sign-attempt.json';
$rawPath = $root . '/fulfill-bad-sign-response.raw';
$receiptPath = $root . '/fulfill-bad-sign-receipt.json';
if (is_file($attemptPath) || is_file($rawPath) || is_file($receiptPath)) {
    throw new RuntimeException('Bad-signature request already attempted');
}
$form = ['machid' => (string)$before['prepay']['machid'],
    'orderid' => $marker, 'torderid' => (string)$prepayId,
    'status' => '1', 'timestamp' => (string)time(),
    'randstr' => bin2hex(random_bytes(16)),
    'sign' => '0000000000000000000000000000000000000000'];
$body = http_build_query($form, '', '&', PHP_QUERY_RFC1738);
$handle = fopen($attemptPath, 'xb');
if (!$handle) throw new RuntimeException('Cannot lock bad-signature request');
fwrite($handle, json_encode(['lane' => $lane, 'marker' => $marker,
    'path' => '/api/prepayOrder/fulfillResult',
    'body_sha256' => hash('sha256', $body), 'at' => date('c')]));
fclose($handle);
chmod($attemptPath, 0600);
$context = stream_context_create(['http' => [
    'method' => 'POST', 'ignore_errors' => true, 'timeout' => 30,
    'header' => "Content-Type: application/x-www-form-urlencoded\r\n"
        . "Host: prepay.code-scan.invalid\r\n",
    'content' => $body,
]]);
$wire = file_get_contents('http://127.0.0.1:' . ($lane === 'B' ? 19131 : 19132)
    . '/api/prepayOrder/fulfillResult', false, $context);
$raw = is_string($wire) ? $wire : '';
$handle = fopen($rawPath, 'xb');
if (!$handle) throw new RuntimeException('Cannot preserve bad-signature response');
fwrite($handle, $raw);
fclose($handle);
chmod($rawPath, 0600);
$status = 0;
foreach (($http_response_header ?? []) as $header) {
    if (preg_match('/^HTTP\/\S+ (\d{3})/', $header, $match)) $status = (int)$match[1];
}
$response = json_decode($raw, true);
$after = $snapshot();
$receipt = ['lane' => $lane, 'marker' => $marker,
    'http_status' => $status,
    'response_json' => is_array($response),
    'response_fields' => is_array($response) ? array_map('gettype', $response) : [],
    'response_code' => $response['code'] ?? null,
    'response_body_sha256' => hash('sha256', $raw),
    'response_raw_file' => basename($rawPath),
    'prepay_exact_unchanged' => $before['prepay'] === $after['prepay'],
    'meal_exact_unchanged' => $before['meal'] === $after['meal'],
    'wallet_exact_unchanged' => $before['wallet'] === $after['wallet'],
    'settlement_exact_unchanged' => $before['settlement'] === $after['settlement']];
$receipt['passed'] = $status === 200 && $receipt['response_json']
    && (string)$receipt['response_code'] === '0'
    && $receipt['prepay_exact_unchanged']
    && $receipt['meal_exact_unchanged']
    && $receipt['wallet_exact_unchanged']
    && $receipt['settlement_exact_unchanged'];
file_put_contents($receiptPath, json_encode($receipt,
    JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES), LOCK_EX);
chmod($receiptPath, 0600);
echo json_encode($receipt, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . PHP_EOL;
exit($receipt['passed'] ? 0 : 1);
