<?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('/^CDXDEL[A-F0-9]{10}$/D', $marker)
    || ($phase === '--run' && getenv('CDX_DISH_DELETE_RUN') !== 'OWN_DISH_AND_RELATION_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;
}
$guid = 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);
};
$dishUuid = $guid($marker . 'dish');
$rowUuid = $guid($marker . 'relation');
$hardwareUuid = $guid($marker . 'hardware');
$one = static function (string $sql, array $args = []) use ($db) {
    $query = $db->prepare($sql);
    $query->execute($args);
    $row = $query->fetch(PDO::FETCH_ASSOC);
    return is_array($row) ? array_change_key_case($row, CASE_LOWER) : null;
};
$ownDish = static function () use ($one, $dishUuid, $marker) {
    return $one('SELECT id,uuid,name,is_study FROM ydy_dishes WHERE uuid=? AND name=?',
        [$dishUuid, $marker]);
};
$ownRelation = static function () use ($one, $rowUuid, $dishUuid, $hardwareUuid) {
    return $one('SELECT id,uuid,dishes_uuid,hardware_uuid'
        . ' FROM ydy_dishes_hardware_img WHERE uuid=? AND dishes_uuid=? AND hardware_uuid=?',
        [$rowUuid, $dishUuid, $hardwareUuid]);
};
$oldDish = $ownDish();
$oldRelation = $ownRelation();
if ($phase === '--audit') {
    echo json_encode(['lane' => $lane, 'phase' => 'audit', 'marker' => $marker,
        'owned_dish_count' => $oldDish === null ? 0 : 1,
        'owned_relation_count' => $oldRelation === null ? 0 : 1,
        'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit($oldDish === null && $oldRelation === null ? 0 : 2);
}
if ($oldDish !== null || $oldRelation !== null) throw new RuntimeException('own marker already exists');
$naturalBefore = $db->query('SELECT id,uuid,is_study FROM ydy_dishes'
    . " WHERE name NOT LIKE 'CDXDEL%' ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
$naturalSha = hash('sha256', json_encode($naturalBefore));
$insertDish = $db->prepare('INSERT INTO ydy_dishes'
    . ' (uuid,name,taste,is_study,category,status,is_del,weight,store_id)'
    . ' VALUES (?,?,0,1,1,1,1,100.00,10001)');
$insertRelation = $db->prepare('INSERT INTO ydy_dishes_hardware_img'
    . ' (uuid,dishes_uuid,hardware_uuid,head_img,create_time) VALUES (?,?,?,?,?)');
$http = static function (array $form) use ($port): array {
    $ctx = stream_context_create(['http' => [
        'method' => 'POST', '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 . '/p/api/delDishesHardwareImg', 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated Store delete HTTP unavailable');
    $raw = stream_get_contents($handle, 131073);
    fclose($handle);
    if (!is_string($raw) || strlen($raw) > 131072) throw new RuntimeException('delete response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('delete HTTP business failure code='
            . (string)($body['code'] ?? 'nonjson')
            . ' message=' . substr((string)($body['message'] ?? ''), 0, 100));
    }
    return $body;
};
$committed = false;
$error = null;
$result = [];
try {
    $db->beginTransaction();
    $insertDish->execute([$dishUuid, $marker]);
    $insertRelation->execute([$rowUuid, $dishUuid, $hardwareUuid, $marker, date('Y-m-d H:i:s')]);
    $dish = $ownDish();
    $relation = $ownRelation();
    if ($dish === null || $relation === null || (int)$dish['is_study'] !== 1) {
        throw new RuntimeException('owned dish/relation insert gate failed');
    }
    $db->commit();
    $committed = true;
    $form = ['dishes_uuid' => $dishUuid, 'hardware_uuid' => $hardwareUuid];
    $first = $http($form);
    $afterFirstDish = $ownDish();
    if ($ownRelation() !== null || $afterFirstDish === null
        || (int)$afterFirstDish['is_study'] !== 0
        || !is_array($first['data'] ?? null) || $first['data'] !== []) {
        throw new RuntimeException('own relation delete or study-state writeback failed');
    }
    $second = $http($form);
    $afterSecondDish = $ownDish();
    if ($ownRelation() !== null || $afterSecondDish === null
        || (int)$afterSecondDish['is_study'] !== 0
        || !is_array($second['data'] ?? null) || $second['data'] !== []) {
        throw new RuntimeException('idempotent second delete failed');
    }
    $result = ['http_business_ok' => 2, 'first_deleted_relation' => true,
        'dish_is_study_one_to_zero' => true,
        'second_delete_idempotent' => true,
        'response_empty_array_both' => true];
} catch (Throwable $caught) {
    $error = $caught;
} finally {
    if ($db->inTransaction()) $db->rollBack();
    if ($committed) {
        $relation = $ownRelation();
        if ($relation !== null) {
            $delete = $db->prepare('DELETE FROM ydy_dishes_hardware_img'
                . ' WHERE id=? AND uuid=? AND dishes_uuid=? AND hardware_uuid=?');
            $delete->execute([(int)$relation['id'], $rowUuid, $dishUuid, $hardwareUuid]);
        }
        $dish = $ownDish();
        if ($dish !== null) {
            $delete = $db->prepare('DELETE FROM ydy_dishes WHERE id=? AND uuid=? AND name=?');
            $delete->execute([(int)$dish['id'], $dishUuid, $marker]);
        }
    }
}
if ($ownDish() !== null || $ownRelation() !== null) throw new RuntimeException('owned dish/relation cleanup failed');
$naturalAfter = $db->query('SELECT id,uuid,is_study FROM ydy_dishes'
    . " WHERE name NOT LIKE 'CDXDEL%' ORDER BY id")->fetchAll(PDO::FETCH_ASSOC);
if (hash('sha256', json_encode($naturalAfter)) !== $naturalSha) {
    throw new RuntimeException('natural dishes source changed');
}
if ($error !== null) throw $error;
echo json_encode(['lane' => $lane, 'marker' => $marker] + $result + [
    'owned_dish_relation_independent_zero' => true,
    'business_dml' => 'own-dish-and-relation-insert-api-delete-study-update-own-dish-cleanup',
    'image_file_oss_requests' => 0,
], JSON_UNESCAPED_SLASHES), PHP_EOL;
