<?php declare(strict_types=1);

namespace Newland\Toubiz\Search\Neos\Tests\Unit\Utility;

use Neos\ContentRepository\Domain\Model\NodeType;
use Neos\ContentRepository\Domain\Service\NodeTypeManager;
use Neos\Flow\Tests\FunctionalTestCase;
use Newland\Toubiz\Search\Neos\Utility\NodeTypeUtility;

class NodeTypeUtilityTest extends FunctionalTestCase
{

    /** @var NodeType */
    protected $childNodeType;

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

    public function setUp(): void
    {
        parent::setUp();
        // See: Configuration/Testing/NodeTypes.yaml
        $nodeTypeManager = $this->objectManager->get(NodeTypeManager::class);
        $this->childNodeType = $nodeTypeManager->getNodeType('Newland.Toubiz.Search.Neos.Testing:Child');
        $this->subject = $this->objectManager->get(NodeTypeUtility::class);
    }

    public function testShouldGetDistanceToSuperTypes(): void
    {
        $distance = $this->subject->getParentNodeTypeDepths($this->childNodeType);

        $this->assertArrayHasKey('Newland.Toubiz.Search.Neos.Testing:Super', $distance);
        $this->assertArrayHasKey('Newland.Toubiz.Search.Neos.Testing:Inbetween', $distance);
        $this->assertArrayHasKey('Newland.Toubiz.Search.Neos.Testing:Child', $distance);

        $this->assertEquals(2, $distance['Newland.Toubiz.Search.Neos.Testing:Super']);
        $this->assertEquals(1, $distance['Newland.Toubiz.Search.Neos.Testing:Inbetween']);
        $this->assertEquals(0, $distance['Newland.Toubiz.Search.Neos.Testing:Child']);
    }

    public function testIgnoresNodeTypeConfigurationNotApplicable(): void
    {
        $config = [
            'Foo.Bar:SomeNodeType' => [ 'foo' => 'bar' ],
            'Newland.Toubiz.Search.Neos.Testing:Child' => [ 'bar' => 'baz' ],
        ];

        $filtered = $this->subject->sortAndFilterConfigurationByNodeType($this->childNodeType, $config);
        $this->assertArrayHasKey('Newland.Toubiz.Search.Neos.Testing:Child', $filtered);
        $this->assertArrayNotHasKey('Foo.Bar:SomeNodeType', $filtered);
    }

    public function testSortsGivenConfigurationByDistanceToNodeType(): void
    {
        $config = [
            'Newland.Toubiz.Search.Neos.Testing:Super' => [ 'bar' => 'baz' ],
            'Newland.Toubiz.Search.Neos.Testing:Child' => [ 'bar' => 'baz' ],
            'Newland.Toubiz.Search.Neos.Testing:Inbetween' => [ 'bar' => 'baz' ],
        ];

        $filtered = $this->subject->sortAndFilterConfigurationByNodeType($this->childNodeType, $config);
        $keys = array_keys($filtered);

        $this->assertEquals('Newland.Toubiz.Search.Neos.Testing:Child', $keys[0]);
        $this->assertEquals('Newland.Toubiz.Search.Neos.Testing:Inbetween', $keys[1]);
        $this->assertEquals('Newland.Toubiz.Search.Neos.Testing:Super', $keys[2]);
    }

}
