<?php

namespace Comitium5\DesignerBundle\Tests\Validator;

use Comitium5\DesignerBundle\Entity\Page;
use Comitium5\DesignerBundle\Entity\Template;
use Comitium5\DesignerBundle\Entity\View;
use Comitium5\DesignerBundle\Entity\Widget;
use Comitium5\DesignerBundle\Model\Interfaces\Page\PageInterface;
use Comitium5\DesignerBundle\Model\Interfaces\Widget\WidgetInterface;
use Comitium5\DesignerBundle\Tests\AbstractTestCase;
use Comitium5\DesignerBundle\Validator\EntityValidator;
use Comitium5\DesignerBundle\Validator\Page\PageHasRelatedTemplateConstraint;
use Comitium5\DesignerBundle\Validator\Page\PageHasRelatedViewConstraint;
use Comitium5\DesignerBundle\Validator\Widget\WidgetNameIsValid;

/**
 * Class EntityValidatorTest
 *
 * @author Carles Gómez <carles@bab-soft.com>
 * @package Comitium5\DesignerBundle\Tests\Validator
 */
class EntityValidatorTest extends AbstractTestCase
{

    /**
     * @dataProvider validatorWidgetData
     *
     * @param WidgetInterface $widget
     * @param array $constraints
     * @param bool $result
     */
    public function testValidateWidget(WidgetInterface $widget, array $constraints, bool $result)
    {
        $validator = new EntityValidator();

        $resultObject = $validator->validate($widget, $constraints);

        $this->assertEquals($result, $resultObject->isValidResult());
    }


    /**
     * @dataProvider validatorPageData
     * @param PageInterface $page
     * @param array $constraints
     * @param bool $result
     */
    public function testValidatePage(PageInterface $page, array $constraints, bool $result)
    {
        $validator = new EntityValidator();

        $resultObject = $validator->validate($page, $constraints);

        $this->assertEquals($result, $resultObject->isValidResult());
    }

    /**
     * @return array[]
     */
    public function validatorPageData(): array
    {
        return [
            [
                $this->page(),
                [
                    new PageHasRelatedTemplateConstraint(),
                    new PageHasRelatedViewConstraint(),
                ],
                true
            ],
            [
                $this->page(false),
                [
                    new PageHasRelatedViewConstraint(),
                ],
                true
            ],
            [
                $this->page(false),
                [
                    new PageHasRelatedTemplateConstraint(),
                ],
                false
            ],
            [
                $this->page(true, false),
                [
                    new PageHasRelatedViewConstraint(),
                ],
                false
            ],
            [
                $this->page(false, false),
                [
                    new PageHasRelatedTemplateConstraint(),
                    new PageHasRelatedViewConstraint(),
                ],
                false
            ],
        ];
    }


    /**
     * @return array[]
     */
    public function validatorWidgetData(): array
    {
        return [
            [
                $this->widget("Foo Bar"),
                [
                    new WidgetNameIsValid()
                ],
                true
            ],
            [
                $this->widget("FooBar"),
                [
                    new WidgetNameIsValid()
                ],
                false
            ],
        ];
    }

    /**
     * @param bool $template
     * @param bool $view
     *
     * @return Page
     */
    private function page(bool $template = true, bool $view = true): PageInterface
    {
        $page = new Page();

        if (true === $template) {
            $page->setTemplate(new Template());
        }

        if (true === $view) {
            $page->addView(new View());
        }

        return $page;
    }

    /**
     * @param string $name
     *
     * @return WidgetInterface
     */
    private function widget(string $name = ""): WidgetInterface
    {
        $widget = new Widget();

        $widget->setName($name);

        return $widget;
    }
}
