<?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 Chill\DocStoreBundle\Tests\GenericDoc\Providers;

use Chill\DocStoreBundle\GenericDoc\FetchQueryToSqlBuilder;
use Chill\DocStoreBundle\GenericDoc\Providers\PersonDocumentGenericDocProvider;
use Chill\DocStoreBundle\Repository\PersonDocumentACLAwareRepositoryInterface;
use Chill\DocStoreBundle\Repository\PersonDocumentRepository;
use Chill\PersonBundle\Entity\Person;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Security;

/**
 * @internal
 *
 * @coversNothing
 */
class PersonDocumentGenericDocProviderTest extends KernelTestCase
{
    use ProphecyTrait;

    private EntityManagerInterface $entityManager;

    private PersonDocumentACLAwareRepositoryInterface $personDocumentACLAwareRepository;

    private PersonDocumentRepository $personDocumentRepository;

    protected function setUp(): void
    {
        self::bootKernel();
        $this->entityManager = self::getContainer()->get(EntityManagerInterface::class);
        $this->personDocumentACLAwareRepository = self::getContainer()->get(PersonDocumentACLAwareRepositoryInterface::class);
        $this->personDocumentRepository = self::getContainer()->get(PersonDocumentRepository::class);
    }

    /**
     * @dataProvider provideDataBuildFetchQueryForPerson
     *
     * @throws \Doctrine\DBAL\Exception
     * @throws \Doctrine\ORM\NoResultException
     * @throws \Doctrine\ORM\NonUniqueResultException
     */
    public function testBuildFetchQueryForPerson(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content): void
    {
        $security = $this->prophesize(Security::class);
        $person = $this->entityManager->createQuery('SELECT a FROM '.Person::class.' a')
            ->setMaxResults(1)
            ->getSingleResult();

        if (null === $person) {
            throw new \UnexpectedValueException('person found');
        }

        $provider = new PersonDocumentGenericDocProvider(
            $security->reveal(),
            $this->personDocumentACLAwareRepository,
            $this->personDocumentRepository,
        );

        $query = $provider->buildFetchQueryForPerson($person, $startDate, $endDate, $content);

        ['sql' => $sql, 'params' => $params, 'types' => $types] = (new FetchQueryToSqlBuilder())->toSql($query);

        $nb = $this->entityManager->getConnection()
            ->fetchOne("SELECT COUNT(*) AS nb FROM ({$sql}) AS sq", $params, $types);

        self::assertIsInt($nb, 'Test that the query is syntactically correct');
    }

    public static function provideDataBuildFetchQueryForPerson(): iterable
    {
        yield [null, null, null];
        yield [new \DateTimeImmutable('1 year ago'), null, null];
        yield [null, new \DateTimeImmutable('1 year ago'), null];
        yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), null];
        yield [null, null, 'test'];
        yield [new \DateTimeImmutable('2 years ago'), new \DateTimeImmutable('1 year ago'), 'test'];
    }
}
