<?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\MainBundle\Tests\Services\AddressGeographicalUnit;

use Chill\MainBundle\Entity\CronJobExecution;
use Doctrine\DBAL\Connection;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Clock\MockClock;

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

    public function testCanRun(): void
    {
        // As the can run is executed one of ten, this should be executed at least one after
        // 10 + 5 executions
        $job = new \Chill\MainBundle\Service\AddressGeographicalUnit\RefreshAddressToGeographicalUnitMaterializedViewCronJob(
            $this->prophesize(Connection::class)->reveal(),
            new MockClock(new \DateTimeImmutable('2023-07-01T00:00:00'))
        );

        $hoursAgo23 = new CronJobExecution($job->getKey());
        $hoursAgo23->setLastStart(new \DateTimeImmutable('2023-06-30T01:00:00'));
        $hoursAgo25 = new CronJobExecution($job->getKey());
        $hoursAgo25->setLastStart(new \DateTimeImmutable('2023-06-29T23:00:00'));

        $executedForFirstTime = $executedAfter23 = $executedAfter25 = 0;

        for ($round = 0; 50 > $round; ++$round) {
            if ($job->canRun(null)) {
                ++$executedForFirstTime;
            }

            if ($job->canRun($hoursAgo23)) {
                ++$executedAfter23;
            }

            if ($job->canRun($hoursAgo25)) {
                ++$executedAfter25;
            }
        }

        $this->assertGreaterThan(0, $executedForFirstTime);
        $this->assertEquals(0, $executedAfter23);
        $this->assertGreaterThan(0, $executedAfter25);
    }

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

        $job = new \Chill\MainBundle\Service\AddressGeographicalUnit\RefreshAddressToGeographicalUnitMaterializedViewCronJob(
            self::getContainer()->get(Connection::class),
            new MockClock()
        );

        $lastExecution = new CronJobExecution($job->getKey());
        $lastExecution->setLastStart(new \DateTimeImmutable('2 days ago'));

        $this->assertIsBool($job->canRun($lastExecution));

        $job->run([]);
    }
}
