<?php declare(strict_types=1);

namespace Newland\Toubiz\Poi\Neos\Tests\Unit\LinkHandler\Filter\Items;

use Neos\Flow\Tests\FunctionalTestCase;
use Newland\NeosTestingHelpers\InteractsWithNodes;
use Newland\Toubiz\Poi\Neos\Filter\ArticleFilterFactory;
use Newland\Toubiz\Poi\Neos\Filter\Items\ArticleRoot;
use Newland\Toubiz\Poi\Neos\Filter\Items\AttributeRange;
use Newland\Toubiz\Sync\Neos\Domain\Model\Article;
use Newland\Toubiz\Sync\Neos\Tests\Factory\ArticleFactory;
use Newland\Toubiz\Sync\Neos\Tests\Factory\AttributeFactory;

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

    /** @var ArticleFactory */
    protected $articleFactory;

    /** @var AttributeFactory */
    protected $attributeFactory;

    /** @var ArticleFilterFactory */
    protected $filterFactory;

    public function setUp(): void
    {
        parent::setUp();
        $this->articleFactory = new ArticleFactory($this->objectManager);
        $this->attributeFactory = new AttributeFactory($this->objectManager);
        $this->filterFactory = new ArticleFilterFactory($this->initializeNode('/sites/foo'));
    }

    public function testFiltersForRangeInclusive(): void
    {
        $article4 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 4 ]) ], ]);
        $article5 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 5 ]) ], ]);
        $article7 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 7 ]) ], ]);
        $article12 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 12 ]) ], ]);
        $article15 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 15 ]) ], ]);
        $article19 = $this->articleFactory->create([ 'attributes' => [ $this->attributeFactory->create([ 'name' => 'num', 'data' => 19 ]) ], ]);

        /** @var ArticleRoot $filter */
        $filter = $this->filterFactory->createFilter(
            [
                'combine' => 'AND',
                'children' => [
                    'num' => [
                        'type' => AttributeRange::class,
                        'queryString' => 'num',
                        'databaseColumn' => 'entity.Persistence_Object_Identifier',
                        'attributeName' => 'num',
                        'attributeType' => 'number',
                        'range' => [ 'min' => 0, 'max' => 20 ]
                    ],
                ],
            ]
        );

        $filter->setState([ 'num' => [ 'min' => 5, 'max' => '15' ] ]);
        $ids = array_map(
            function (Article $article) {
                return $article->getPersistenceObjectIdentifier();
            },
            $filter->getArticleQuery()->getQuery()->execute()
        );

        $this->assertNotContains($article4->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should not find 4');
        $this->assertContains($article5->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should find 5');
        $this->assertContains($article7->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should find 7');
        $this->assertContains($article12->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should find 12');
        $this->assertContains($article15->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should find 15');
        $this->assertNotContains($article19->getPersistenceObjectIdentifier(), $ids, 'Range between 5 and 15 should not find 19');
    }

}
