<?php declare(strict_types=1);

namespace Newland\NeosCommon\Tests\Unit\Service;

use Neos\Flow\Mvc\Routing\ObjectPathMapping;
use Neos\Flow\Mvc\Routing\ObjectPathMappingRepository;
use Neos\Flow\Tests\FunctionalTestCase;
use Newland\NeosCommon\Service\ControllerContextFactory;
use Newland\NeosCommon\Service\ObjectPathMappingService;
use Newland\NeosCommon\Tests\Factory\ObjectPathMappingFactory;
use Newland\Toubiz\Poi\Neos\LinkHandler\ArticleLinkHandler;
use Newland\Toubiz\Poi\Neos\Service\ArticleUrlService;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Newland\Toubiz\Sync\Neos\Tests\Factory\ArticleFactory;

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

    /** @var ObjectPathMappingRepository */
    protected $mappingRepository;

    /** @var ObjectPathMappingService */
    protected $subject;

    /** @var ObjectPathMappingFactory */
    protected $factory;

    /** @var ArticleUrlService */
    protected $linkingService;

    public function setUp(): void
    {
        parent::setUp();
        $this->subject = $this->objectManager->get(ObjectPathMappingService::class);
        $this->mappingRepository = $this->objectManager->get(ObjectPathMappingRepository::class);
        $this->factory = new ObjectPathMappingFactory($this->objectManager);
    }

    public function testClearsAllMappings(): void
    {
        [ $first, $second, $third ] = $this->factory->createMultiple(3, [ 'objectType' => 'Foo\Bar' ]);

        $ids = $this->getMappedIds();
        $this->assertContains($first->getIdentifier(), $ids);
        $this->assertContains($second->getIdentifier(), $ids);
        $this->assertContains($third->getIdentifier(), $ids);

        $this->subject->flushMappings('Foo\Bar');

        $ids = $this->getMappedIds();
        $this->assertNotContains($first->getIdentifier(), $ids);
        $this->assertNotContains($second->getIdentifier(), $ids);
        $this->assertNotContains($third->getIdentifier(), $ids);
    }

    public function testClearsOnlyGivenMappings(): void
    {
        [ $first, $second, $third ] = $this->factory->createMultiple(3, [ 'objectType' => 'Foo\Bar' ]);

        $ids = $this->getMappedIds();
        $this->assertContains($first->getIdentifier(), $ids);
        $this->assertContains($second->getIdentifier(), $ids);
        $this->assertContains($third->getIdentifier(), $ids);

        $this->subject->flushMappings('Foo\Bar', [ $first->getIdentifier(), $third->getIdentifier() ]);

        $ids = $this->getMappedIds();
        $this->assertNotContains($first->getIdentifier(), $ids);
        $this->assertContains($second->getIdentifier(), $ids);
        $this->assertNotContains($third->getIdentifier(), $ids);
    }

    private function getMappedIds(): array
    {
        return array_map(
            function(ObjectPathMapping $mapping) { return $mapping->getIdentifier(); },
            $this->mappingRepository->findAll()->toArray()
        );
    }

}
