<?php declare(strict_types=1);

namespace Newland\Toubiz\Sync\Neos\Tests\Unit\Domain\Model;

use Neos\Flow\Tests\FunctionalTestCase;
use Newland\Toubiz\Sync\Neos\Domain\Model\Event;
use Newland\Toubiz\Sync\Neos\Domain\Model\EventDate;
use Newland\Toubiz\Sync\Neos\Domain\Repository\RecordConfigurationRepository;
use Newland\Toubiz\Sync\Neos\Tests\Factory\EventDateFactory;
use Newland\Toubiz\Sync\Neos\Tests\Factory\EventFactory;

class EventTest extends FunctionalTestCase
{
    protected static $testablePersistenceEnabled = true;

    /**
     * @dataProvider provideDeterministicIds
     * @param string $expectedId
     * @param array $properties
     */
    public function testDeterministicIdsAreGeneratedCorrectly(string $expectedId, array $properties): void
    {
        self::assertEquals(
            $expectedId,
            (new EventFactory($this->objectManager))->make($properties)->generateUuid()->toString(),
            'persistence object identifier should be stable: If this test fails then the'
            . ' way ids are being generated has probably changed and old identifiers need to be migrated'
            . ' to this new style.'
        );
    }

    /**
     * @dataProvider provideDeterministicIds
     * @param string $expectedId
     * @param array $properties
     */
    public function testDeterministicIdsAreAutomaticallyGeneratedWhenStoringInDatabase(
        string $expectedId,
        array $properties
    ): void {
        /** @var Event $event */
        $event = (new EventFactory($this->objectManager))->create($properties);

        self::assertEquals(
            $expectedId,
            $event->getPersistenceObjectIdentifier(),
            'persistence object identifier should be stable: If this test fails then the'
            . ' way ids are being generated has probably changed and old identifiers need to be migrated'
            . ' to this new style.'
        );

        // Entity is explicitly deleted to avoid id collisions.
        $this->persistenceManager->remove($event);
        $this->persistenceManager->persistAll();
    }

    public function provideDeterministicIds(): array
    {
        return [
            'baseEvent' => [
                '149b01d9-c846-5b26-9425-670c02ec72d4',
                [
                    'language' => 'de',
                    'originalId' => 'lalala',
                    'title' => 'First name',
                    'client' => 'd8a1d47d-3192-4d8e-bf80-1b4d1404f8d1',
                ],
            ],
            'sameAsBaseButDifferentName: Should have same identifier' => [
                '149b01d9-c846-5b26-9425-670c02ec72d4',
                [
                    'language' => 'de',
                    'originalId' => 'lalala',
                    'title' => 'Same basic event as before but with different name.',
                    'client' => 'd8a1d47d-3192-4d8e-bf80-1b4d1404f8d1',
                ],
            ],
            'languageChanged' => [
                '9b377eb5-5c7e-57ef-a142-10b5f01d085b',
                [
                    'language' => 'en',
                    'originalId' => 'lalala',
                    'client' => 'd8a1d47d-3192-4d8e-bf80-1b4d1404f8d1',
                ],
            ],
            'originalIdChanged' => [
                '99607480-ddfb-5302-b318-d3f7b39aa1a9',
                [
                    'language' => 'de',
                    'originalId' => 'blablabla',
                    'client' => 'd8a1d47d-3192-4d8e-bf80-1b4d1404f8d1',
                ],
            ],
            'clientChanged' => [
                '6e026ace-b7e9-58a6-813e-c1cfc400cc1e',
                [
                    'language' => 'de',
                    'originalId' => 'lalala',
                    'client' => 'entenhausen',
                ],
            ],
            'differentPropertiesAllTogether' => [
                '2fb790ab-f768-548d-ae59-c007c8a52302',
                [
                    'language' => 'fr',
                    'originalId' => 'foooooo',
                    'client' => 'entenhausen',
                ],
            ],
        ];
    }

    public function testConfiguringAnEventToBeHiddenAlsoHidesAllDates(): void
    {
        $event = (new EventFactory($this->objectManager))->create([]);
        $date = (new EventDateFactory($this->objectManager))->create([ 'event' => $event ]);
        $this->persistenceManager->clearState();
        /** @var Event $event */
        $event = $this->persistenceManager
            ->getObjectByIdentifier($event->getPersistenceObjectIdentifier(), Event::class);
        $date = $this->persistenceManager
            ->getObjectByIdentifier($date->getPersistenceObjectIdentifier(), EventDate::class);

        self::assertFalse($event->isHidden());
        self::assertFalse($date->isHidden());

        $this->objectManager->get(RecordConfigurationRepository::class)->updateConfiguration(
            $event,
            static function () {
                return [ 'hidden' => true ];
            }
        );

        $event = $this->persistenceManager
            ->getObjectByIdentifier($event->getPersistenceObjectIdentifier(), Event::class);
        $date = $this->persistenceManager
            ->getObjectByIdentifier($date->getPersistenceObjectIdentifier(), EventDate::class);

        self::assertTrue($event->isHidden());
        self::assertTrue($date->isHidden());
    }

}
