<?php

declare(strict_types=1);

use Tests\Support\OpsUx\SourceFileScanner;

function providerDispatchGateSlice(string $source, string $startAnchor, ?string $endAnchor = null): string
{
    $start = strpos($source, $startAnchor);

    expect($start)->not->toBeFalse();

    $start = is_int($start) ? $start : 0;

    if ($endAnchor === null) {
        return substr($source, $start);
    }

    $end = strpos($source, $endAnchor, $start + strlen($startAnchor));

    expect($end)->not->toBeFalse();

    $end = is_int($end) ? $end : strlen($source);

    return substr($source, $start, $end - $start);
}

it('keeps first-slice route-bounded provider starts on canonical gate-owned entry points', function (): void {
    $root = SourceFileScanner::projectRoot();

    $checks = [
        [
            'file' => $root.'/app/Services/Verification/StartVerification.php',
            'start' => 'public function providerConnectionCheckForTenant(',
            'end' => 'public function providerConnectionCheckUsingConnection(',
            'required' => [
                'return $this->providers->start(',
                "operationType: 'provider.connection.check'",
                "'required_capability' => Capabilities::PROVIDER_RUN",
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Services/Verification/StartVerification.php',
            'start' => 'public function providerConnectionCheckUsingConnection(',
            'end' => 'private function dispatchConnectionHealthCheck(',
            'required' => [
                '$result = $this->providers->start(',
                "operationType: 'provider.connection.check'",
                'ProviderVerificationStatus::Pending',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Services/Directory/EntraGroupSyncService.php',
            'start' => 'public function startManualSync(',
            'end' => 'public function sync(',
            'required' => [
                'return $this->providerStarts->start(',
                'operationType: OperationRunType::DirectoryGroupsSync->value',
                'EntraGroupSyncJob::dispatch(',
                '->afterCommit()',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Services/Directory/RoleDefinitionsSyncService.php',
            'start' => 'public function startManualSync(',
            'end' => 'public function sync(',
            'required' => [
                'return $this->providerStarts->start(',
                'operationType: OperationRunType::DirectoryRoleDefinitionsSync->value',
                'SyncRoleDefinitionsJob::dispatch(',
                '->afterCommit()',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Resources/RestoreRunResource.php',
            'start' => 'private static function startQueuedRestoreExecution(',
            'end' => 'private static function detailPreviewState(',
            'required' => [
                'app(ProviderOperationStartGate::class)->start(',
                "operationType: 'restore.execute'",
                'ExecuteRestoreRunJob::dispatch(',
                '->afterCommit()',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Resources/EntraGroupResource/Pages/ListEntraGroups.php',
            'start' => "Action::make('sync_groups')",
            'end' => '->requireCapability(Capabilities::TENANT_SYNC)',
            'required' => [
                '$syncService->startManualSync($tenant, $user)',
                'ProviderOperationStartResultPresenter::class',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Resources/ManagedEnvironmentResource.php',
            'start' => 'public static function syncRoleDefinitionsAction(): Actions\\Action',
            'end' => null,
            'required' => [
                '$result = $syncService->startManualSync($record, $user);',
                'ProviderOperationStartResultPresenter::class',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Resources/ProviderConnectionResource.php',
            'start' => 'private static function handleCheckConnectionAction(',
            'end' => 'private static function handleProviderOperationAction(',
            'required' => [
                '$verification->providerConnectionCheck(',
                'ProviderOperationStartResultPresenter::class',
                'OperationRunLinks::view($result->run, $tenant)',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Resources/ProviderConnectionResource.php',
            'start' => 'private static function handleProviderOperationAction(',
            'end' => 'public static function getEloquentQuery(): Builder',
            'required' => [
                '$result = $gate->start(',
                'ProviderOperationStartResultPresenter::class',
                'OperationRunLinks::view($result->run, $tenant)',
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
        [
            'file' => $root.'/app/Filament/Pages/Workspaces/ManagedEnvironmentOnboardingWizard.php',
            'start' => 'public function startBootstrap(array $operationTypes): void',
            'end' => 'private function dispatchBootstrapJob(',
            'required' => [
                'app(ProviderOperationStartGate::class)->start(',
                'ProviderOperationStartResultPresenter::class',
                "'bootstrap_operation_types'",
            ],
            'forbidden' => ['ensureRun(', 'dispatchOrFail('],
        ],
    ];

    foreach ($checks as $check) {
        $source = SourceFileScanner::read($check['file']);
        $slice = providerDispatchGateSlice($source, $check['start'], $check['end']);

        foreach ($check['required'] as $needle) {
            expect($slice)->toContain($needle);
        }

        foreach ($check['forbidden'] as $needle) {
            expect($slice)->not->toContain($needle);
        }
    }
})->group('surface-guard');
