<?php

declare(strict_types=1);

use App\Support\Governance\GovernanceDomainKey;
use App\Support\Governance\GovernanceSubjectClass;
use App\Support\Governance\GovernanceSubjectTaxonomyRegistry;

it('composes active governance subject types from current policy and foundation metadata', function (): void {
    $registry = app(GovernanceSubjectTaxonomyRegistry::class);

    $subjectTypes = collect($registry->active())
        ->keyBy(static fn ($subjectType): string => $subjectType->subjectTypeKey)
        ->all();

    expect($subjectTypes['deviceConfiguration']->domainKey)->toBe(GovernanceDomainKey::Intune)
        ->and($subjectTypes['deviceConfiguration']->subjectClass)->toBe(GovernanceSubjectClass::Policy)
        ->and($subjectTypes['deviceConfiguration']->captureSupported)->toBeTrue()
        ->and($subjectTypes['deviceConfiguration']->compareSupported)->toBeTrue()
        ->and($subjectTypes['deviceConfiguration']->legacyBucket)->toBe('policy_types')
        ->and($subjectTypes['assignmentFilter']->domainKey)->toBe(GovernanceDomainKey::PlatformFoundation)
        ->and($subjectTypes['assignmentFilter']->subjectClass)->toBe(GovernanceSubjectClass::ConfigurationResource)
        ->and($subjectTypes['assignmentFilter']->legacyBucket)->toBe('foundation_types')
        ->and(array_key_exists('intuneRoleAssignment', $subjectTypes))->toBeFalse();
});

it('keeps unsupported foundation mappings addressable but inactive in the complete registry', function (): void {
    $registry = app(GovernanceSubjectTaxonomyRegistry::class);
    $subjectType = $registry->find('platform_foundation', 'intuneRoleAssignment');

    expect($subjectType)->not->toBeNull()
        ->and($subjectType?->active)->toBeFalse()
        ->and($subjectType?->captureSupported)->toBeFalse()
        ->and($subjectType?->compareSupported)->toBeFalse();
});

it('reserves future-domain vocabulary without exposing future domains as active operator selections', function (): void {
    $registry = app(GovernanceSubjectTaxonomyRegistry::class);

    expect($registry->isKnownDomain('entra'))->toBeTrue()
        ->and($registry->allowsSubjectClass('entra', 'control'))->toBeTrue()
        ->and(collect($registry->active())->contains(
            static fn ($subjectType): bool => $subjectType->domainKey === GovernanceDomainKey::Entra,
        ))->toBeFalse();
});

it('finds subject types by subject key across legacy buckets and exposes contributor ownership metadata', function (): void {
    $registry = app(GovernanceSubjectTaxonomyRegistry::class);

    expect($registry->findBySubjectTypeKey('deviceConfiguration')?->domainKey)->toBe(GovernanceDomainKey::Intune)
        ->and($registry->findBySubjectTypeKey('assignmentFilter', 'foundation_types')?->subjectClass)->toBe(GovernanceSubjectClass::ConfigurationResource)
        ->and($registry->ownershipDescriptor()->canonicalNouns)->toBe(['domain_key', 'subject_class', 'subject_type_key', 'subject_type_label']);
});