<?php

namespace App\Services\Intune;

use Illuminate\Container\Attributes\Tag;

class PolicyNormalizer
{
    /**
     * @var array<int, PolicyTypeNormalizer>
     */
    private array $typeNormalizers;

    public function __construct(
        private readonly DefaultPolicyNormalizer $defaultNormalizer,
        #[Tag('policy-type-normalizers')]
        iterable $typeNormalizers = [],
    ) {
        $normalizers = is_array($typeNormalizers)
            ? $typeNormalizers
            : iterator_to_array($typeNormalizers);

        $this->typeNormalizers = array_values(array_filter(
            $normalizers,
            fn (mixed $normalizer) => $normalizer instanceof PolicyTypeNormalizer
        ));
    }

    /**
     * @return array{status: string, settings: array<int, array<string, mixed>>, settings_table?: array<string, mixed>, warnings: array<int, string>}
     */
    public function normalize(?array $snapshot, string $policyType, ?string $platform = null): array
    {
        return $this->resolveNormalizer($policyType)
            ->normalize($snapshot, $policyType, $platform);
    }

    /**
     * @return array<string, mixed>
     */
    public function flattenForDiff(?array $snapshot, string $policyType, ?string $platform = null): array
    {
        return $this->resolveNormalizer($policyType)
            ->flattenForDiff($snapshot, $policyType, $platform);
    }

    /**
     * @param  array<int, mixed>  $settings
     * @return array{type: string, groups: array<int, array<string, mixed>>}
     */
    public function normalizeSettingsCatalogGrouped(array $settings): array
    {
        return $this->defaultNormalizer->normalizeSettingsCatalogGrouped($settings);
    }

    private function resolveNormalizer(string $policyType): PolicyTypeNormalizer
    {
        foreach ($this->typeNormalizers as $normalizer) {
            if ($normalizer->supports($policyType)) {
                return $normalizer;
            }
        }

        return $this->defaultNormalizer;
    }
}
