<?php declare(strict_types=1);

namespace Newland\Toubiz\Events\Neos\Tests\Unit\PageFrame;

use Neos\ContentRepository\Domain\Model\Node;
use Neos\Flow\Tests\FunctionalTestCase;
use Neos\Neos\TypeConverter\EntityToIdentityConverter;
use Newland\NeosTestingHelpers\InteractsWithNodes;
use Newland\PageFrameProvider\Service\PageFrameContextService;
use Newland\Toubiz\Events\Neos\PageFrame\EventBreadcrumbProvider;
use Newland\Toubiz\Sync\Neos\Domain\Model\Event;
use Newland\Toubiz\Sync\Neos\Tests\Factory\EventFactory;

class EventBreadcrumbProviderTest extends FunctionalTestCase
{
    use InteractsWithNodes;
    protected static $testablePersistenceEnabled = true;


    /** @var Node[] */
    protected $nodes;

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

    /** @var Event */
    protected $event;

    public function setUp(): void
    {
        parent::setUp();

        $this->subject = $this->objectManager->get(EventBreadcrumbProvider::class);
        $this->event = (new EventFactory($this->objectManager))->create();
        $this->objectManager->get(PageFrameContextService::class)
            ->setPluginArguments([ 'event' => $this->event->getPersistenceObjectIdentifier() ]);

        $this->nodes = [
            'site-test' => $this->initializeNode('/sites/site-test', static::class),
            'foo' => $this->initializeNode('/sites/site-test/foo', static::class),
            'bar' => $this->initializeNode('/sites/site-test/bar', static::class),
            'baz' => $this->initializeNode('/sites/site-test/baz', static::class),
        ];
    }


    public function testFetchesNodesAsConfigured(): void
    {
        $this->setupBreadcrumbConfig([
             'site-test' => [ '/sites/site-test/foo', '/sites/site-test/bar' ],
         ]);

        $nodes = $this->subject->selectBreadCrumbs($this->nodes['site-test'], []);
        $this->assertCount(3, $nodes);
        $this->assertEquals('site-test', $nodes[0]->getName());
        $this->assertEquals('foo', $nodes[1]->getName());
        $this->assertEquals('bar', $nodes[2]->getName());
    }

    public function testUsesFallbackIfNothingConfigured(): void
    {
        $this->setupBreadcrumbConfig([
             'site-another' => [ '/sites/site-test/foo', '/sites/site-test/bar' ],
             '_fallback' => [ '/sites/site-test/baz' ],
         ]);

        $nodes = $this->subject->selectBreadCrumbs($this->nodes['site-test'], []);
        $this->assertCount(2, $nodes);
        $this->assertEquals('site-test', $nodes[0]->getName());
        $this->assertEquals('baz', $nodes[1]->getName());
    }

    public function testUsesOldStyleConfigurationIfFallbackNotAvailable(): void
    {
        $this->setupBreadcrumbConfig([
             'site-another' => [ '/sites/site-test/bar' ],
             '/sites/site-test/baz',
             '/sites/site-test/foo'
         ]);

        $nodes = $this->subject->selectBreadCrumbs($this->nodes['site-test'], []);
        $this->assertCount(3, $nodes);
        $this->assertEquals('site-test', $nodes[0]->getName());
        $this->assertEquals('baz', $nodes[1]->getName());
        $this->assertEquals('foo', $nodes[2]->getName());
    }

    public function testSelectsArticleWhenPassingAsFlowObject(): void
    {
        $this->setupBreadcrumbConfig([ '/sites/site-test/baz', '/sites/site-test/foo' ]);
        $this->objectManager->get(PageFrameContextService::class)
            ->setPluginArguments([ 'article' => (new EntityToIdentityConverter())->convertFrom($this->event, null) ]);

        $nodes = $this->subject->selectBreadCrumbs($this->nodes['site-test'], []);
        $this->assertGreaterThan(0, \count($nodes));
    }

    private function setupBreadcrumbConfig(array $breadcrumb): void
    {
        $this->inject(
            $this->subject,
            'types',
            [
                'default' => [
                    'uriSegment' => 'foo/bar',
                    'breadcrumb' => $breadcrumb,
                ],
            ]
        );
    }

}
