<?php
declare(strict_types=1);

$phase = (string)($argv[1] ?? '');
if (!in_array($phase, ['--audit', '--run'], true)
    || ($phase === '--run' && getenv('CDX_TREE_FIXED_RUN') !== 'ONE_DISABLED_TEST_USER_V1')) {
    fwrite(STDERR, "DENIED business_http=0 business_dml=0\n"); exit(78);
}
$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 Store 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]);
$fixedUuid = '4A544AFA-7911-9C6A-124D-EFBF1684AAD0';
$marker = 'CDXTREE20261009';
$count = static function (string $sql, array $args = []) use ($db): int {
    $stmt = $db->prepare($sql); $stmt->execute($args); return (int)$stmt->fetchColumn();
};
$owned = static function () use ($count, $fixedUuid, $marker): array {
    return [$count('SELECT COUNT(*) FROM ydy_user WHERE uuid=? AND account=? AND create_by=?',
        [$fixedUuid, $marker, 'CODEX']),
        $count('SELECT COUNT(*) FROM ydy_user_data WHERE user_uuid=?', [$fixedUuid])];
};
$before = $owned();
$relationStmt = $db->prepare('SELECT * FROM ydy_user_data WHERE user_uuid=? ORDER BY id');
$relationStmt->execute([$fixedUuid]);
$preexistingRelations = $relationStmt->fetchAll(PDO::FETCH_ASSOC);
if ($phase === '--audit') {
    $allFixed = $count('SELECT COUNT(*) FROM ydy_user WHERE uuid=?', [$fixedUuid]);
    echo json_encode(['lane' => 'B', 'phase' => 'audit', 'fixed_user_count' => $allFixed,
        'owned_user_and_relations' => $before, 'business_http' => 0, 'business_dml' => 0]), PHP_EOL;
    exit($allFixed === 0 && $before[0] === 0 ? 0 : 2);
}
if ($before[0] !== 0 || $count('SELECT COUNT(*) FROM ydy_user WHERE uuid=?', [$fixedUuid]) !== 0) {
    throw new RuntimeException('fixed user UUID already present');
}
$sourceRows = $db->query('SELECT uuid,name,puuid FROM ydy_department'
    . ' WHERE is_show=1 AND status=1 ORDER BY id')->fetchAll(PDO::FETCH_ASSOC);
if (!$sourceRows) throw new RuntimeException('no B active source departments');
$source = [];
foreach ($sourceRows as $row) $source[(string)$row['uuid']] = $row;
$error = null; $output = [];
try {
    $insert = $db->prepare('INSERT INTO ydy_user'
        . ' (uuid,account,pwd,salt,name,type,create_time,create_by,is_delete)'
        . ' VALUES (?,?,?,?,?,?,?,?,?)');
    $insert->execute([$fixedUuid, $marker, 'DISABLED', strtoupper(bin2hex(random_bytes(8))),
        $marker, 0, date('Y-m-d H:i:s'), 'CODEX', 0]);
    if ($owned() !== [1, $before[1]]) throw new RuntimeException('fixed disabled test user not uniquely inserted');
    $ctx = stream_context_create(['http' => [
        'method' => 'POST', 'header' => "Content-Type: application/x-www-form-urlencoded\r\n",
        'content' => '', 'ignore_errors' => true, 'timeout' => 25, 'follow_location' => 0]]);
    $handle = @fopen('http://127.0.0.1:18081/p/api/tree', 'rb', false, $ctx);
    if (!is_resource($handle)) throw new RuntimeException('isolated B Store tree HTTP unavailable');
    $raw = stream_get_contents($handle, 8388609); fclose($handle);
    if (!is_string($raw) || strlen($raw) > 8388608) throw new RuntimeException('tree response cap');
    $body = json_decode($raw, true);
    if (!is_array($body) || (int)($body['code'] ?? -1) !== 0) {
        throw new RuntimeException('tree business failure');
    }
    $data = $body['data'] ?? null;
    if (!is_array($data) || !is_array($data['department'] ?? null)
        || !is_array($data['project'] ?? null) || !$data['department']) {
        throw new RuntimeException('tree lacks positive department branch');
    }
    $seen = [];
    $firstTypes = null;
    $walk = static function (array $nodes) use (&$walk, &$seen, &$firstTypes, $source): void {
        foreach ($nodes as $node) {
            if (!is_array($node)) throw new RuntimeException('tree node malformed');
            $uuid = (string)($node['uuid'] ?? '');
            if ($uuid === '' || isset($seen[$uuid]) || !isset($source[$uuid])
                || (string)($node['name'] ?? '') !== (string)$source[$uuid]['name']) {
                throw new RuntimeException('tree node differs from original source');
            }
            $seen[$uuid] = true;
            if ($firstTypes === null) {
                $leaf = $node; unset($leaf['children']);
                ksort($leaf); $firstTypes = array_map('gettype', $leaf);
            }
            if (isset($node['children'])) $walk($node['children']);
        }
    };
    $walk($data['department']);
    if (!$seen || count($seen) > count($source)) throw new RuntimeException('positive tree node count invalid');
    $output = ['lane' => 'B', 'business_http_ok' => 1,
        'source_department_count' => count($source), 'matched_tree_nodes' => count($seen),
        'first_node_type_sha' => hash('sha256', json_encode($firstTypes)),
        'first_node_types' => $firstTypes,
        'project_node_count' => count($data['project'])];
} catch (Throwable $caught) { $error = $caught; }
finally {
    if ($owned()[0] === 1) {
        $stmt = $db->prepare('DELETE FROM ydy_user WHERE uuid=? AND account=? AND create_by=?');
        $stmt->execute([$fixedUuid, $marker, 'CODEX']);
    }
}
if ($owned() !== [0, $before[1]] || $count('SELECT COUNT(*) FROM ydy_user WHERE uuid=?', [$fixedUuid]) !== 0) {
    throw new RuntimeException('fixed disabled test user cleanup failed');
}
$relationStmt->execute([$fixedUuid]);
if ($relationStmt->fetchAll(PDO::FETCH_ASSOC) !== $preexistingRelations) {
    throw new RuntimeException('preexisting fixed-UUID permission rows changed');
}
if ($error !== null) throw $error;
$afterRows = $db->query('SELECT uuid,name,puuid FROM ydy_department'
    . ' WHERE is_show=1 AND status=1 ORDER BY id')->fetchAll(PDO::FETCH_ASSOC);
if ($afterRows !== $sourceRows) throw new RuntimeException('original department rows changed');
$output['fixed_user_cleanup_zero'] = true;
$output['original_department_unchanged'] = true;
echo json_encode($output, JSON_UNESCAPED_SLASHES), PHP_EOL;
