<?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\AccompanyingCourseDocumentGenericDocProvider;
use Chill\DocStoreBundle\Repository\AccompanyingCourseDocumentRepository;
use Chill\DocStoreBundle\Security\Authorization\AccompanyingCourseDocumentVoter;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Doctrine\ORM\EntityManagerInterface;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Security\Core\Security;

/**
 * @internal
 *
 * @coversNothing
 */
class AccompanyingCourseDocumentGenericDocProviderTest extends KernelTestCase
{
    use ProphecyTrait;
    private EntityManagerInterface $entityManager;

    public function setUp(): void
    {
        self::bootKernel();

        $this->entityManager = self::getContainer()->get(EntityManagerInterface::class);
    }

    /**
     * @dataProvider provideSearchArguments
     */
    public function testWithoutAnyArgument(?\DateTimeImmutable $startDate, ?\DateTimeImmutable $endDate, ?string $content = null): void
    {
        $period = $this->entityManager->createQuery('SELECT a FROM '.AccompanyingPeriod::class.' a')
            ->setMaxResults(1)
            ->getSingleResult();

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

        $security = $this->prophesize(Security::class);
        $security->isGranted(AccompanyingCourseDocumentVoter::SEE, $period)
            ->willReturn(true);

        $provider = new AccompanyingCourseDocumentGenericDocProvider(
            $security->reveal(),
            $this->entityManager,
            $this->prophesize(AccompanyingCourseDocumentRepository::class)->reveal()
        );

        $query = $provider->buildFetchQueryForAccompanyingPeriod($period, $startDate, $endDate, $content);

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

        $nb = $this->entityManager->getConnection()->executeQuery('SELECT COUNT(*) FROM ('.$sql.') AS sq', $params, $types)
            ->fetchOne();

        self::assertIsInt($nb);
    }

    public static function provideSearchArguments(): iterable
    {
        yield [null, null, null];
        yield [new \DateTimeImmutable('1 month ago'), null, null];
        yield [new \DateTimeImmutable('1 month ago'), new \DateTimeImmutable('now'), null];
        yield [null, null, 'test'];
    }
}
