<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\PersonBundle\Tests\PersonIdentifier\Normalizer;

use Chill\PersonBundle\Entity\Identifier\PersonIdentifier;
use Chill\PersonBundle\Entity\Identifier\PersonIdentifierDefinition;
use Chill\PersonBundle\PersonIdentifier\Normalizer\PersonIdentifierWorkerNormalizer;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierEngineInterface;
use Chill\PersonBundle\PersonIdentifier\PersonIdentifierWorker;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;

/**
 * @internal
 *
 * @coversNothing
 */
class PersonIdentifierWorkerNormalizerTest extends TestCase
{
    public function testSupportsNormalization(): void
    {
        $engine = new class () implements PersonIdentifierEngineInterface {
            public static function getName(): string
            {
                return 'dummy';
            }

            public function canonicalizeValue(array $value, PersonIdentifierDefinition $definition): ?string
            {
                return null;
            }

            public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}

            public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
            {
                return '';
            }

            public function isEmpty(PersonIdentifier $identifier): bool
            {
                return false;
            }

            public function validate(PersonIdentifier $identifier, PersonIdentifierDefinition $definition): array
            {
                return [];
            }

            public function getDefaultValue(PersonIdentifierDefinition $definition): array
            {
                return [];
            }
        };

        $definition = new PersonIdentifierDefinition(label: ['en' => 'SSN'], engine: 'string');
        $worker = new PersonIdentifierWorker($engine, $definition);

        $normalizer = new PersonIdentifierWorkerNormalizer();

        self::assertTrue($normalizer->supportsNormalization($worker));
        self::assertFalse($normalizer->supportsNormalization(new \stdClass()));
    }

    public function testNormalizeReturnsExpectedArray(): void
    {
        $engine = new class () implements PersonIdentifierEngineInterface {
            public static function getName(): string
            {
                return 'dummy';
            }

            public function canonicalizeValue(array $value, PersonIdentifierDefinition $definition): ?string
            {
                return null;
            }

            public function buildForm(\Symfony\Component\Form\FormBuilderInterface $builder, PersonIdentifierDefinition $personIdentifierDefinition): void {}

            public function renderAsString(?PersonIdentifier $identifier, PersonIdentifierDefinition $definition): string
            {
                return '';
            }

            public function isEmpty(PersonIdentifier $identifier): bool
            {
                return false;
            }

            public function getDefaultValue(PersonIdentifierDefinition $definition): array
            {
                return [];
            }

            public function validate(PersonIdentifier $identifier, PersonIdentifierDefinition $definition): array
            {
                return [];
            }
        };

        $definition = new PersonIdentifierDefinition(label: ['en' => 'SSN'], engine: 'string');
        $definition->setActive(false);
        $worker = new PersonIdentifierWorker($engine, $definition);

        $normalizer = new PersonIdentifierWorkerNormalizer();
        $normalized = $normalizer->normalize($worker);

        self::assertSame([
            'type' => 'person_identifier_worker',
            'definition_id' => null,
            'engine' => 'string',
            'label' => ['en' => 'SSN'],
            'isActive' => false,
            'presence' => 'ON_EDIT',
        ], $normalized);
    }

    public function testNormalizeThrowsOnInvalidObject(): void
    {
        $normalizer = new PersonIdentifierWorkerNormalizer();
        $this->expectException(UnexpectedValueException::class);
        $normalizer->normalize(new \stdClass());
    }
}
