<?php

use App\Services\Baselines\InventoryMetaContract;
use App\Support\Inventory\InventoryPolicyTypeMeta;

it('builds a deterministic v1 contract regardless of input ordering', function () {
    $builder = app(InventoryMetaContract::class);

    $a = $builder->build(
        policyType: 'deviceConfiguration',
        subjectExternalId: 'policy-a',
        metaJsonb: [
            'etag' => 'E1',
            'odata_type' => '#microsoft.graph.deviceConfiguration',
            'scope_tag_ids' => ['2', '1'],
            'assignment_target_count' => 3,
        ],
    );

    $b = $builder->build(
        policyType: 'deviceConfiguration',
        subjectExternalId: 'policy-a',
        metaJsonb: [
            'assignment_target_count' => 3,
            'scope_tag_ids' => ['1', '2'],
            'odata_type' => '#microsoft.graph.deviceConfiguration',
            'etag' => 'E1',
        ],
    );

    expect($a)->toBe($b);
});

it('represents missing signals as null (not omitted)', function () {
    $builder = app(InventoryMetaContract::class);

    $contract = $builder->build(
        policyType: 'deviceConfiguration',
        subjectExternalId: 'policy-a',
        metaJsonb: [],
    );

    expect($contract)->toHaveKeys([
        'version',
        'policy_type',
        'subject_external_id',
        'odata_type',
        'etag',
        'scope_tag_ids',
        'assignment_target_count',
    ]);

    expect($contract['version'])->toBe(1);
    expect($contract['policy_type'])->toBe('deviceConfiguration');
    expect($contract['subject_external_id'])->toBe('policy-a');
    expect($contract['odata_type'])->toBeNull();
    expect($contract['etag'])->toBeNull();
    expect($contract['scope_tag_ids'])->toBeNull();
    expect($contract['assignment_target_count'])->toBeNull();
});

it('keeps baseline support contracts aligned with governance mapping for policies and foundations', function (): void {
    $policyContract = InventoryPolicyTypeMeta::baselineSupportContract('deviceConfiguration');
    $foundationContract = InventoryPolicyTypeMeta::baselineSupportContract('intuneRoleDefinition');
    $unsupportedFoundationContract = InventoryPolicyTypeMeta::baselineSupportContract('intuneRoleAssignment');

    expect($policyContract)->toMatchArray([
        'config_supported' => true,
        'runtime_valid' => true,
        'subject_class' => 'policy_backed',
        'resolution_path' => 'policy',
        'compare_capability' => 'supported',
        'capture_capability' => 'supported',
        'source_model_expected' => 'policy',
    ])->and($foundationContract)->toMatchArray([
        'config_supported' => true,
        'runtime_valid' => true,
        'subject_class' => 'foundation_backed',
        'resolution_path' => 'foundation_policy',
        'compare_capability' => 'supported',
        'capture_capability' => 'supported',
        'source_model_expected' => 'policy',
    ])->and($unsupportedFoundationContract)->toMatchArray([
        'config_supported' => false,
        'runtime_valid' => true,
        'subject_class' => 'foundation_backed',
        'resolution_path' => 'foundation_policy',
        'compare_capability' => 'unsupported',
        'capture_capability' => 'unsupported',
        'source_model_expected' => 'policy',
    ]);
});
