<?php

declare(strict_types=1);

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

it('normalizes legacy policy_type payloads into governed-subject descriptors', function (): void {
    $result = app(PlatformSubjectDescriptorNormalizer::class)->fromArray([
        'policy_type' => 'deviceConfiguration',
    ], 'baseline_compare');

    expect($result->usedLegacyAlias)->toBeTrue()
        ->and($result->descriptor->domainKey)->toBe(GovernanceDomainKey::Intune->value)
        ->and($result->descriptor->subjectClass)->toBe(GovernanceSubjectClass::Policy->value)
        ->and($result->descriptor->subjectTypeKey)->toBe('deviceConfiguration')
        ->and($result->descriptor->platformNoun)->toBe('Governed subject');
});

it('builds governed-subject descriptors for canonical baseline scope entries', function (): void {
    $descriptors = app(PlatformSubjectDescriptorNormalizer::class)->descriptorsForScopeEntries([
        [
            'domain_key' => GovernanceDomainKey::PlatformFoundation->value,
            'subject_class' => GovernanceSubjectClass::ConfigurationResource->value,
            'subject_type_keys' => ['assignmentFilter'],
            'filters' => [],
        ],
    ]);

    expect($descriptors)->toHaveCount(1)
        ->and(data_get($descriptors, '0.descriptor.subject_type_key'))->toBe('assignmentFilter')
        ->and(data_get($descriptors, '0.descriptor.domain_key'))->toBe(GovernanceDomainKey::PlatformFoundation->value)
        ->and(data_get($descriptors, '0.source_surface'))->toBe('baseline_scope');
});

it('falls back to compatibility-only descriptors for unknown subject types', function (): void {
    $result = app(PlatformSubjectDescriptorNormalizer::class)->fromArray([
        'policy_type' => 'mysterySubject',
    ], 'snapshot');

    expect($result->usedLegacyAlias)->toBeTrue()
        ->and($result->descriptor->subjectTypeKey)->toBe('mysterySubject')
        ->and($result->warnings)->not->toBeEmpty();
});