<?php

declare(strict_types=1);

use App\Support\Governance\Controls\CanonicalControlCatalog;
use App\Support\Governance\Controls\CanonicalControlResolutionRequest;
use App\Support\Governance\Controls\CanonicalControlResolver;

it('lists seeded canonical controls in the logical contract shape', function (): void {
    $payload = [
        'controls' => app(CanonicalControlCatalog::class)->listPayload(),
    ];

    expect($payload['controls'])->not->toBeEmpty();

    foreach ($payload['controls'] as $control) {
        expect($control)->toHaveKeys([
            'control_key',
            'name',
            'domain_key',
            'subdomain_key',
            'control_class',
            'summary',
            'operator_description',
            'detectability_class',
            'evaluation_strategy',
            'evidence_archetypes',
            'artifact_suitability',
            'historical_status',
        ])->and($control['artifact_suitability'])->toHaveKeys([
            'baseline',
            'drift',
            'finding',
            'exception',
            'evidence',
            'review',
            'report',
        ]);
    }
});

it('returns resolved, unresolved, and ambiguous resolution shapes without guessing', function (): void {
    $resolver = app(CanonicalControlResolver::class);

    $resolved = $resolver->resolve(new CanonicalControlResolutionRequest(
        provider: 'microsoft',
        consumerContext: 'review',
        subjectFamilyKey: 'entra_admin_roles',
        workload: 'entra',
        signalKey: 'entra_admin_roles.global_admin_assignment',
    ))->toArray();
    $unresolved = $resolver->resolve(new CanonicalControlResolutionRequest(
        provider: 'microsoft',
        consumerContext: 'review',
        subjectFamilyKey: 'not_bound',
    ))->toArray();
    $ambiguous = $resolver->resolve(new CanonicalControlResolutionRequest(
        provider: 'microsoft',
        consumerContext: 'review',
        subjectFamilyKey: 'conditional_access_policy',
        workload: 'entra',
    ))->toArray();

    expect($resolved)->toHaveKeys(['status', 'control'])
        ->and($resolved['status'])->toBe('resolved')
        ->and($resolved['control']['control_key'])->toBe('privileged_access_governance')
        ->and($unresolved)->toHaveKeys(['status', 'reason_code', 'binding_context'])
        ->and($unresolved['reason_code'])->toBe('missing_binding')
        ->and($ambiguous)->toHaveKeys(['status', 'reason_code', 'candidate_control_keys', 'binding_context'])
        ->and($ambiguous['status'])->toBe('ambiguous')
        ->and($ambiguous['candidate_control_keys'])->toEqualCanonicalizing([
            'conditional_access_enforcement',
            'strong_authentication',
        ]);
});
