<?php
declare(strict_types=1);

require __DIR__ . '/read6_fixture_plan.php';

function fixture(): array
{
    $checks = array_fill_keys([
        'runtime_identity', 'owned_ai_user', 'owned_store_user', 'store_mapping',
        'file_token', 'password_version_match', 'short_ttl', 'external_stubs',
        'queue_isolated', 'file_logs_baselined', 'two_database_probe',
        'source_fingerprint', 'cleanup_journal',
    ], true);
    $counts = array_fill_keys([
        'cashout_order', 'recharge_order', 'course', 'archive_related',
        'user_data_related',
    ], 1);
    $lane = static function (string $database, string $physical, string $owner)
        use ($checks, $counts): array {
        return [
            'database' => $database, 'physical' => $physical, 'owner' => $owner,
            'checks' => $checks, 'counts' => $counts,
            'weight_goal_exists' => true, 'staff_exists' => true,
            'coze_whitelisted' => true, 'local_wallet_allowed' => true,
        ];
    };
    return [
        'marker' => 'CDX_READ6_20261004',
        'lanes' => [
            'A' => $lane('dev-mysql', 'dev-db-fingerprint', 'dev-owner'),
            'B' => $lane('dev-mysql', 'dev-db-fingerprint', 'dev-owner'),
            'C' => $lane('dm-test', 'dm-db-fingerprint', 'dm-owner'),
        ],
    ];
}

function expect(bool $condition, string $message): void
{
    if (!$condition) {
        throw new RuntimeException($message);
    }
}

$all = fixture();
$plan = read6_fixture_decide($all);
expect($plan['status'] === 'offline_plan_only', 'valid fixture should yield offline plan');
foreach (['A', 'B', 'C'] as $lane) {
    expect(count($plan['lanes'][$lane]) === 6, 'six fixed routes per lane');
    expect(count(array_filter($plan['lanes'][$lane], static function ($route) {
        return $route['state'] === 'candidate_for_live_recheck';
    })) === 6, 'all valid routes still need live source recheck');
}

expect(read6_fixture_decide([])['status'] === 'blocked', 'missing fixture must block');
$wrong = fixture();
$wrong['lanes']['B']['physical'] = 'another-dev-db';
expect(read6_fixture_decide($wrong)['status'] === 'blocked', 'A/B physical drift must block');
$wrong = fixture();
$wrong['lanes']['C']['physical'] = 'dev-db-fingerprint';
expect(read6_fixture_decide($wrong)['status'] === 'blocked', 'C must be isolated');
$wrong = fixture();
$wrong['lanes']['A']['checks']['password_version_match'] = false;
expect(read6_fixture_decide($wrong)['status'] === 'blocked', 'token version mismatch must block');
$wrong = fixture();
$wrong['lanes']['A']['counts']['cashout_order'] = 101;
expect($wrong['lanes']['A']['counts']['cashout_order'] === 101, 'negative fixture');
expect(read6_fixture_decide($wrong)['lanes']['A'][1]['state'] === 'skip',
    'over 100 owned cashout rows must skip list');
$wrong = fixture();
$wrong['lanes']['A']['weight_goal_exists'] = false;
expect(read6_fixture_decide($wrong)['lanes']['A'][4]['state'] === 'skip',
    'Archive must skip without an existing weight goal');
$wrong = fixture();
$wrong['lanes']['A']['coze_whitelisted'] = false;
expect(read6_fixture_decide($wrong)['lanes']['A'][5]['state'] === 'skip',
    'User/data positive branch must skip without whitelist');
$empty = fixture();
$empty['lanes']['A']['counts']['cashout_order'] = 0;
$empty['lanes']['A']['counts']['course'] = 0;
$emptyPlan = read6_fixture_decide($empty);
expect($emptyPlan['lanes']['A'][1]['branch'] === 'empty_only'
    && $emptyPlan['lanes']['A'][3]['branch'] === 'empty_only',
    'empty source cannot be reported as a positive branch');
echo "read6 offline gate tests: 9 green\n";
