<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Validation\Validator;

use Chill\PersonBundle\Entity\Person;
use Chill\TicketBundle\Action\Ticket\SetPersonsCommand;
use Chill\TicketBundle\Validation\Validator\SetPersonCommandConstraint;
use Chill\TicketBundle\Validation\Validator\SetPersonCommandConstraintValidator;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\Validator\Test\ConstraintValidatorTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
class SetPersonCommandConstraintValidatorTest extends ConstraintValidatorTestCase
{
    private string $personPerTicket = 'many';

    protected function createValidator()
    {
        return new SetPersonCommandConstraintValidator(
            new ParameterBag(['chill_ticket' => ['ticket' => ['person_per_ticket' => $this->personPerTicket]]])
        );
    }

    /**
     * Helper method to set the configuration and recreate the validator.
     */
    private function setPersonPerTicket(string $personPerTicket): void
    {
        $this->personPerTicket = $personPerTicket;
        $this->validator = $this->createValidator();
        $this->validator->initialize($this->context);
    }

    public function testValidatorWithManyPersonsPerTicket(): void
    {
        $this->setPersonPerTicket('multi');

        $command = new SetPersonsCommand([new Person(), new Person()]);

        $this->validator->validate($command, new SetPersonCommandConstraint());

        $this->assertNoViolation();
    }

    public function testValidatorWithSinglePersonPerTicket(): void
    {
        $this->setPersonPerTicket('single');

        $command = new SetPersonsCommand([new Person(), new Person()]);

        $this->validator->validate($command, $command = new SetPersonCommandConstraint());

        $this->buildViolation($command->notMulti)->atPath('property.path.persons')->assertRaised();
    }

    public function testValidatorWithSinglePersonPerTicketAndEmptyPersons(): void
    {
        $this->setPersonPerTicket('single');

        $command = new SetPersonsCommand([]);

        $this->validator->validate($command, new SetPersonCommandConstraint());

        $this->assertNoViolation();
    }

    public function testValidatorWithSinglePersonPerTicketAndOnlyOnePerson(): void
    {
        $this->setPersonPerTicket('single');

        $command = new SetPersonsCommand([new Person()]);

        $this->validator->validate($command, new SetPersonCommandConstraint());

        $this->assertNoViolation();
    }
}
