<?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\ThirdPartyBundle\Tests\Serializer\Normalizer;

use Chill\MainBundle\Entity\Civility;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Entity\ThirdPartyCategory;
use libphonenumber\PhoneNumberUtil;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

/**
 * @internal
 *
 * @coversNothing
 */
final class ThirdPartyDocGenNormalizerTest extends KernelTestCase
{
    private NormalizerInterface $normalizer;

    private PhoneNumberUtil $phoneNumberUtil;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->normalizer = self::getContainer()->get(NormalizerInterface::class);
        $this->phoneNumberUtil = PhoneNumberUtil::getInstance();
    }

    public function testAvoidRecursionWithNullParent()
    {
        $thirdparty = new ThirdParty();
        $thirdparty
            ->setAcronym('ABCD')
            ->setName('test')
            ->setCivility((new Civility())->setName(['fr' => 'Monsieur'])->setAbbreviation(['fr' => 'M.']))
            ->setEmail('info@cl.coop')
            ->addTypesAndCategories('kind')
            ->addTypesAndCategories((new ThirdPartyCategory())->setName(['fr' => 'category']))
            ->setParent(new ThirdParty());

        $actual = $this->normalizer->normalize($thirdparty, 'docgen', ['groups' => ['docgen:read']]);

        $this->assertIsArray($actual);
        $this->assertArrayHasKey('parent', $actual);
        $this->assertIsArray($actual['parent']);
        $this->assertArrayNotHasKey('parent', $actual['parent']);
        // check that other keys exists for parent
        $this->assertArrayHasKey('acronym', $actual['parent']);
        $this->assertEquals('', $actual['parent']['acronym']);

        $thirdparty = new ThirdParty();
        $thirdparty
            ->setAcronym('ABCD')
            ->setName('test')
            ->setCivility((new Civility())->setName(['fr' => 'Monsieur'])->setAbbreviation(['fr' => 'M.']))
            ->setEmail('info@cl.coop')
            ->addTypesAndCategories('kind')
            ->addTypesAndCategories((new ThirdPartyCategory())->setName(['fr' => 'category']));

        $actual = $this->normalizer->normalize($thirdparty, 'docgen', ['groups' => ['docgen:read']]);

        $this->assertIsArray($actual);
        $this->assertArrayHasKey('parent', $actual);
        $this->assertIsArray($actual['parent']);
        $this->assertArrayNotHasKey('parent', $actual['parent']);
        // check that other keys exists for parent
        $this->assertArrayHasKey('acronym', $actual['parent']);
        $this->assertEquals('', $actual['parent']['acronym']);

        $actual = $this->normalizer->normalize(null, 'docgen', ['groups' => ['docgen:read'], 'docgen:expects' => ThirdParty::class]);

        $this->assertIsArray($actual);
        $this->assertArrayHasKey('parent', $actual);
        $this->assertIsArray($actual['parent']);
        $this->assertArrayNotHasKey('parent', $actual['parent']);
        // check that other keys exists for parent
        $this->assertArrayHasKey('acronym', $actual['parent']);
        $this->assertEquals('', $actual['parent']['acronym']);
    }

    public function testNormalize()
    {
        $thirdparty = new ThirdParty();
        $thirdparty
            ->setAcronym('ABCD')
            ->setName('test')
            ->setCivility((new Civility())->setName(['fr' => 'Monsieur'])->setAbbreviation(['fr' => 'M.']))
            ->setEmail('info@cl.coop')
            ->setTelephone($this->phoneNumberUtil->parse('+32486123456', 'BE'))
            ->addTypesAndCategories('kind')
            ->addTypesAndCategories((new ThirdPartyCategory())->setName(['fr' => 'category']));

        $actual = $this->normalizer->normalize($thirdparty, 'docgen', ['groups' => ['docgen:read']]);

        $this->assertIsArray($actual);
        $this->assertArrayHasKey('telephone', $actual);
        $this->assertEquals('0486 12 34 56', $actual['telephone']);
    }
}
