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

use Chill\CalendarBundle\Entity\Calendar;
use Chill\MainBundle\Entity\Embeddable\CommentEmbeddable;
use Chill\MainBundle\Entity\User;
use Chill\PersonBundle\Entity\Person;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;

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

    protected function setUp(): void
    {
        self::bootKernel();

        $this->normalizer = self::getContainer()->get(NormalizerInterface::class);
    }

    public function testNormalizationCalendar()
    {
        $calendar = (new Calendar())
            ->setComment(
                $comment = new CommentEmbeddable()
            )
            ->setStartDate(\DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, '2020-10-15T15:00:00+0000'))
            ->setEndDate(\DateTimeImmutable::createFromFormat(\DateTimeImmutable::ATOM, '2020-15-15T15:30:00+0000'))
            ->addPerson(new Person())
            ->addPerson(new Person())
            ->addUser(new User())
            ->addProfessional(new ThirdParty());

        $expected = [
            'type' => 'chill_calendar_calendar',
            'isNull' => false,
            'urgent' => false,
            'sendSMS' => false,
        ];

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

        // we first check for the known key/value...
        foreach ($expected as $key => $value) {
            $this->assertArrayHasKey($key, $actual);
            $this->assertEquals($value, $actual[$key]);
        }

        // ... and then check for some other values
        $this->assertArrayHasKey('persons', $actual);
        $this->assertIsArray($actual['persons']);
        $this->assertArrayHasKey('invites', $actual);
        $this->assertIsArray($actual['invites']);
        $this->assertArrayHasKey('startDate', $actual);
        $this->assertIsArray($actual['startDate']);
        $this->assertArrayHasKey('endDate', $actual);
        $this->assertIsArray($actual['endDate']);
        $this->assertArrayHasKey('professionals', $actual);
        $this->assertIsArray($actual['professionals']);
        $this->assertArrayHasKey('location', $actual);
        $this->assertIsArray($actual['location']);
        $this->assertArrayHasKey('mainUser', $actual);
        $this->assertIsArray($actual['mainUser']);
        $this->assertArrayHasKey('comment', $actual);
        $this->assertIsArray($actual['comment']);
        $this->assertArrayHasKey('duration', $actual);
        $this->assertIsArray($actual['duration']);
    }

    public function testNormalizationOnNullHasSameKeys()
    {
        $calendar = new Calendar();

        $notNullCalendar = $this->normalizer->normalize(
            $calendar,
            'docgen',
            ['groups' => ['docgen:read'], 'docgen:expects' => Calendar::class]
        );

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

        $this->assertEqualsCanonicalizing(array_keys($notNullCalendar), array_keys($isNullCalendar));
    }
}
