<?php

/*
 * @author TRYDEA - 2024
 */

namespace Webapp\FileManagement\Service\XmlUtils\Normalizer\Mobile;

use Mobile\Measure\Entity\Test\Base\Test;
use Mobile\Measure\Entity\Variable\Base\Variable;
use Symfony\Component\Serializer\Exception\ExceptionInterface;
use Symfony\Component\Serializer\Normalizer\ContextAwareDenormalizerInterface;
use Symfony\Component\Serializer\Serializer;
use Symfony\Component\Serializer\SerializerAwareInterface;
use Symfony\Component\Serializer\SerializerAwareTrait;
use Webapp\FileManagement\Dto\Mobile\VariableAndTestDto;
use Webapp\FileManagement\Service\XmlUtils\CustomXmlEncoder;
use Webapp\FileManagement\Service\XmlUtils\Normalizer\AbstractXmlNormalizer;

class VariableAndTestDtoNormalizer implements ContextAwareDenormalizerInterface, SerializerAwareInterface
{
    use SerializerAwareTrait;

    public function supportsDenormalization($data, string $type, ?string $format = null, array $context = []): bool
    {
        return VariableAndTestDto::class === $type;
    }

    /**
     * @throws ExceptionInterface
     */
    public function denormalize($data, string $type, ?string $format = null, array $context = []): VariableAndTestDto
    {
        \assert($this->serializer instanceof Serializer);

        $object = new VariableAndTestDto();
        $object->variable = $this->serializer->denormalize($data, Variable::class, $format, $context);
        $object->testDtos = $data['tests'] ?? [];

        $readerHelper = AbstractXmlNormalizer::getReaderHelper($context);
        $reference = $readerHelper->createReference($context[AbstractXmlNormalizer::REFERENCE]->getReference(), 'variables', $data[CustomXmlEncoder::NODE_INDEX]);
        $readerHelper->add($reference, $object->variable);

        return $object;
    }

    /**
     * @param VariableAndTestDto[] $data
     *
     * @return Variable[]
     *
     * @throws ExceptionInterface
     */
    public static function getVariablesAndCreateTests(array $data, Serializer $serializer): array
    {
        $variables = [];
        foreach ($data as $datum) {
            if (null === $datum->variable) {
                throw new \LogicException('Variable $datum->variable is null');
            }

            $variables[] = $datum->variable;
            foreach ($datum->testDtos as $item) {
                $test = $serializer->denormalize($item, Test::class);
                $datum->variable->addTest($test);
            }
        }

        return $variables;
    }
}
