<?php declare(strict_types=1);

namespace Newland\NeosFiltering\Tests\Unit\Items;

use Newland\Contracts\Neos\Filter\Expression;
use Newland\NeosFiltering\Items\CheckboxList;
use Newland\NeosFiltering\Items\ObstructionWrapper;
use Newland\NeosFiltering\Items\Root;
use Newland\NeosFiltering\RangeSource\DirectRangeSource;
use Newland\NeosFiltering\Tests\Fixture\DataSource\ExampleDataSource;
use Newland\NeosFiltering\Tests\Fixture\ItemMock;

class ObstructionWrapperTest extends ItemTestCase
{

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

    /** @var ItemMock */
    protected $obstructed;

    public function setUp(): void
    {
        parent::setUp();
        $this->obstructed = new ItemMock();
        $this->subject = new ObstructionWrapper($this->obstructed);
    }

    public function testRendersNothing(): void
    {
        $this->obstructed->renderingResultToReturn = 'Something';
        $this->assertEmpty($this->renderSubject());
    }

    public function testHandsDownQueryApplications(): void
    {
        $expression = Expression::empty();
        $this->obstructed->expressionGenerator = function() use ($expression) {
            return $expression;
        };

        $this->assertEquals($expression, $this->subject->queryExpression($this->entityManager->getExpressionBuilder()));
    }

    public function testHandsDownStateSetting(): void
    {
        $this->subject->setState([ 'foo' ]);
        $this->assertEquals([ 'foo' ], $this->obstructed->state);
    }

    public function testHandsDownCombinationSetting(): void
    {
        $root = new Root();
        $checkbox = new CheckboxList();
        $checkbox->setRoot($root);
        $subject = new ObstructionWrapper($checkbox);
        $subject->setRoot($root);

        $subject->setCombine('AND');
        $this->assertEquals('AND', $checkbox->getCombine());

        $subject->setCombine('OR');
        $this->assertEquals('OR', $checkbox->getCombine());
    }

    public function testHandsDownDataSource(): void
    {
        $checkbox = new CheckboxList();
        $subject = new ObstructionWrapper($checkbox);

        $source = new ExampleDataSource();
        $subject->setDataSource($source);
        $this->assertEquals($source,  $checkbox->getDataSource());
    }

    public function testHandsDownDataSourceArguments(): void
    {
        $checkbox = new CheckboxList();
        $subject = new ObstructionWrapper($checkbox);

        $subject->setDataSourceArguments([ 'hello', 'from', 'the', 'other', 'side' ]);
        $this->assertEquals([ 'hello', 'from', 'the', 'other', 'side' ],  $checkbox->getDataSourceArguments());
    }

    public function testHandsDownRangeSource(): void
    {
        $source = new DirectRangeSource();
        $this->subject->setRangeSource($source);
        $this->assertEquals($source, $this->obstructed->rangeSource);
    }

    public function testClonesChildrenItemsWhenCloningRoot(): void
    {
        $foo = new ItemMock('Foo', null, 'foo');
        $subject = new ObstructionWrapper($foo);

        $this->assertSame($foo, $subject->getObstructed());
        $this->assertNotSame($foo, (clone $subject)->getObstructed());
    }

}
