<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
$lane = (string)($argv[2] ?? '');
$marker = (string)($argv[3] ?? '');
if (!in_array($phase, ['--run', '--audit'], true) || !in_array($lane, ['B', 'C'], true)
    || !preg_match('/^CDXIMG[A-F0-9]{10}$/D', $marker)
    || ($phase === '--run' && getenv('CDX_DISH_IMG_RUN') !== 'ONE_DB_METADATA_ROW_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
if ($lane === 'B') {
    $config = include '/tmp/zhct-http-store-mysql.dQTTBP/application/config/local/database.php';
    if (!is_array($config) || ($config['database'] ?? '') !== 'zhct'
        || hash('sha256', (string)($config['hostname'] ?? ''))
            !== '47e8be48b0cfd56dcdb9d9d426e6637b245f340b4efad4cd2f084ec5851ecc8e') {
        throw new RuntimeException('B code-local MySQL identity drift');
    }
    $db = new PDO('mysql:host=' . $config['hostname'] . ';port=3306;dbname=zhct;charset=utf8',
        $config['username'], $config['password'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    $port = 18081;
} else {
    if (getenv('POC_DIALECT') !== 'dm' || getenv('POC_HOST') !== '127.0.0.1'
        || getenv('POC_PORT') !== '5237' || getenv('POC_SCHEMA') !== 'ZHCT_APP'
        || getenv('POC_USER') !== 'ZHCT_APP') {
        throw new RuntimeException('C isolated Store DM identity drift');
    }
    $db = new PDO('dm:host=127.0.0.1;port=5237;schema=ZHCT_APP',
        getenv('POC_USER'), getenv('POC_PASSWORD'),
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_CASE => PDO::CASE_LOWER]);
    if ($db->query("SELECT SYS_CONTEXT('USERENV','CURRENT_SCHEMA') FROM DUAL")->fetchColumn() !== 'ZHCT_APP') {
        throw new RuntimeException('C schema drift');
    }
    $port = 18080;
}
$uuidFromMarker = static function (string $seed): string {
    $hex = strtoupper(substr(hash('sha256', $seed), 0, 32));
    return substr($hex, 0, 8) . '-' . substr($hex, 8, 4) . '-'
        . substr($hex, 12, 4) . '-' . substr($hex, 16, 4)
        . '-' . substr($hex, 20, 12);
};
$rowUuid = $uuidFromMarker($marker . 'row');
$hardwareUuid = $uuidFromMarker($marker . 'hardware');
$ownRows = static function () use ($db, $rowUuid, $hardwareUuid): array {
    $stmt = $db->prepare('SELECT id,uuid,dishes_uuid,hardware_uuid,head_img,create_time'
        . ' FROM ydy_dishes_hardware_img WHERE uuid=? AND hardware_uuid=?');
    $stmt->execute([$rowUuid, $hardwareUuid]);
    return array_map(static function (array $row): array {
        return array_change_key_case($row, CASE_LOWER);
    }, $stmt->fetchAll(PDO::FETCH_ASSOC));
};
$before = $ownRows();
if ($phase === '--audit') {
    echo json_encode(['lane' => $lane, 'phase' => 'audit', 'marker' => $marker,
        'owned_relation_count' => count($before),
        'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit($before ? 2 : 0);
}
if ($before) throw new RuntimeException('owned image relation marker already exists');
$dishSql = 'SELECT uuid,name FROM ydy_dishes WHERE is_del=1 AND status=1'
    . ' AND category=1 ORDER BY id ASC'
    . ($lane === 'B' ? ' LIMIT 1' : ' FETCH FIRST 1 ROWS ONLY');
$dish = $db->query($dishSql)->fetch(PDO::FETCH_ASSOC);
if (!is_array($dish)) throw new RuntimeException('no original active dish');
$dish = array_change_key_case($dish, CASE_LOWER);
$naturalBefore = $db->query('SELECT id,uuid,dishes_uuid,hardware_uuid FROM ydy_dishes_hardware_img'
    . ' ORDER BY id')->fetchAll(PDO::FETCH_ASSOC);
$http = static function (string $path, string $method = 'GET', array $form = []) use ($port): array {
    if (!in_array($path, ['/p/api/getAllHardwareDishes', '/p/api/getDishesHardwareImg'], true)
        || !in_array($method, ['GET', 'POST'], true)) {
        throw new RuntimeException('unsupported fixed image metadata route');
    }
    $ctx = stream_context_create(['http' => [
        'method' => $method, 'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => http_build_query($form, '', '&', PHP_QUERY_RFC3986),
        'ignore_errors' => true, 'timeout' => 15, 'follow_location' => 0,
    ]]);
    $handle = @fopen('http://127.0.0.1:' . $port . $path, 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated image metadata HTTP unavailable');
    $raw = stream_get_contents($handle, 524289);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 524288) throw new RuntimeException('image metadata response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('image metadata HTTP failure at ' . $path
            . ' code=' . (string)($body['code'] ?? 'nonjson'));
    }
    return $body;
};
$insert = $db->prepare('INSERT INTO ydy_dishes_hardware_img'
    . ' (uuid,dishes_uuid,hardware_uuid,head_img,create_time) VALUES (?,?,?,?,?)');
$error = null;
$result = [];
try {
    $now = date('Y-m-d H:i:s');
    $insert->execute([$rowUuid, $dish['uuid'], $hardwareUuid, $marker, $now]);
    $rows = $ownRows();
    if (count($rows) !== 1 || (string)$rows[0]['dishes_uuid'] !== (string)$dish['uuid']
        || (string)$rows[0]['head_img'] !== $marker) {
        throw new RuntimeException('own relation insert/readback failed');
    }
    $all = $http('/p/api/getAllHardwareDishes')['data'] ?? null;
    $single = $http('/p/api/getDishesHardwareImg', 'POST', [
        'dishes_uuid' => $dish['uuid'], 'hardware_uuid' => $hardwareUuid])['data'] ?? null;
    $ownAll = is_array($all) ? array_values(array_filter($all,
        static function ($row) use ($rowUuid): bool {
            return is_array($row) && (string)($row['uuid'] ?? '') === $rowUuid;
        })) : null;
    if (!is_array($ownAll) || count($ownAll) !== 1
        || (int)($ownAll[0]['id'] ?? 0) !== (int)$rows[0]['id']
        || (string)($ownAll[0]['dishes_uuid'] ?? '') !== (string)$dish['uuid']
        || (string)($ownAll[0]['hardware_uuid'] ?? '') !== $hardwareUuid
        || !is_array($single) || count($single) !== 1
        || (string)($single[0]['head_img'] ?? '') !== $marker
        || (string)($single[0]['dishes_uuid'] ?? '') !== (string)$dish['uuid']
        || (string)($single[0]['hardware_uuid'] ?? '') !== $hardwareUuid) {
        throw new RuntimeException('two image metadata HTTP responses differ from own row');
    }
    $typeHash = static function (array $row): string {
        $map = [];
        foreach ($row as $field => $value) $map[$field] = gettype($value);
        ksort($map);
        return hash('sha256', json_encode($map));
    };
    $result = ['http_business_ok' => 2, 'own_relation_source_equal' => true,
        'all_item_type_sha256' => $typeHash($ownAll[0]),
        'single_item_type_sha256' => $typeHash($single[0])];
} catch (Throwable $caught) {
    $error = $caught;
} finally {
    foreach ($ownRows() as $ownedRow) {
        $stmt = $db->prepare('DELETE FROM ydy_dishes_hardware_img'
            . ' WHERE id=? AND uuid=? AND hardware_uuid=?');
        $stmt->execute([(int)$ownedRow['id'], $rowUuid, $hardwareUuid]);
    }
}
if ($ownRows()) throw new RuntimeException('owned image relation cleanup failed');
$naturalAfter = $db->query('SELECT id,uuid,dishes_uuid,hardware_uuid FROM ydy_dishes_hardware_img'
    . ' ORDER BY id')->fetchAll(PDO::FETCH_ASSOC);
if ($naturalBefore !== $naturalAfter) throw new RuntimeException('natural image relations changed');
if ($error !== null) throw $error;
echo json_encode(['lane' => $lane, 'marker' => $marker] + $result + [
    'owned_relation_cleanup_zero' => true,
    'business_dml' => 'one-own-db-metadata-row-insert-then-delete',
    'image_file_oss_requests' => 0,
], JSON_UNESCAPED_SLASHES), PHP_EOL;
