<?php

declare(strict_types=1);

namespace App\Support\Baselines;

final class BaselineSupportCapabilityGuard
{
    public function __construct(
        private readonly SubjectResolver $resolver,
    ) {}

    public function inspectType(string $policyType): SupportCapabilityRecord
    {
        return $this->resolver->capability($policyType);
    }

    /**
     * @param  list<string>  $policyTypes
     * @return array{
     *   allowed_types: list<string>,
     *   limited_types: list<string>,
     *   unsupported_types: list<string>,
     *   invalid_support_types: list<string>,
     *   capabilities: array<string, array<string, mixed>>
     * }
     */
    public function guardTypes(array $policyTypes, string $operation): array
    {
        $allowedTypes = [];
        $limitedTypes = [];
        $unsupportedTypes = [];
        $invalidSupportTypes = [];
        $capabilities = [];

        foreach (array_values(array_unique(array_filter($policyTypes, 'is_string'))) as $policyType) {
            $record = $this->inspectType($policyType);
            $mode = $record->supportModeFor($operation);

            $capabilities[$policyType] = array_merge(
                $record->toArray(),
                ['support_mode' => $mode],
            );

            if ($mode === 'invalid_support_config') {
                $invalidSupportTypes[] = $policyType;
                $unsupportedTypes[] = $policyType;

                continue;
            }

            if ($record->allows($operation)) {
                $allowedTypes[] = $policyType;

                if ($mode === 'limited') {
                    $limitedTypes[] = $policyType;
                }

                continue;
            }

            $unsupportedTypes[] = $policyType;
        }

        sort($allowedTypes, SORT_STRING);
        sort($limitedTypes, SORT_STRING);
        sort($unsupportedTypes, SORT_STRING);
        sort($invalidSupportTypes, SORT_STRING);
        ksort($capabilities);

        return [
            'allowed_types' => $allowedTypes,
            'limited_types' => $limitedTypes,
            'unsupported_types' => $unsupportedTypes,
            'invalid_support_types' => $invalidSupportTypes,
            'capabilities' => $capabilities,
        ];
    }
}
