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

use Chill\MainBundle\Entity\CronJobExecution;
use Chill\MainBundle\Service\AddressGeographicalUnit\CollateAddressWithReferenceOrPostalCodeCronJob;
use Chill\MainBundle\Service\AddressGeographicalUnit\CollateAddressWithReferenceOrPostalCodeInterface;
use PHPUnit\Framework\TestCase;
use Prophecy\PhpUnit\ProphecyTrait;
use Symfony\Component\Clock\MockClock;

/**
 * @internal
 *
 * @coversNothing
 */
class CollateAddressWithReferenceOrPostalCodeCronJobTest extends TestCase
{
    use ProphecyTrait;

    /**
     * @dataProvider provideDataCanRun
     */
    public function testCanRun(\DateTimeImmutable $now, ?\DateTimeImmutable $lastExecution, bool $expected): void
    {
        $execution = match ($lastExecution) {
            null => null,
            default => (new CronJobExecution('collate-address'))->setLastStart($lastExecution),
        };

        $clock = new MockClock($now);
        $collator = $this->prophesize(CollateAddressWithReferenceOrPostalCodeInterface::class);

        $job = new CollateAddressWithReferenceOrPostalCodeCronJob($clock, $collator->reveal());

        self::assertEquals($expected, $job->canRun($execution));
    }

    public static function provideDataCanRun(): iterable
    {
        yield [new \DateTimeImmutable('2023-07-10T12:00:00'), new \DateTimeImmutable('2023-07-10T11:00:00'), false];
        yield [new \DateTimeImmutable('2023-07-10T12:00:00'), new \DateTimeImmutable('2023-07-10T05:00:00'), true];
        yield [new \DateTimeImmutable('2023-07-10T12:00:00'), new \DateTimeImmutable('2023-07-01T12:00:00'), true];
        yield [new \DateTimeImmutable('2023-07-10T12:00:00'), null, true];
    }

    public function testRun(): void
    {
        $clock = new MockClock();
        $collator = $this->prophesize(CollateAddressWithReferenceOrPostalCodeInterface::class);
        $collator->__invoke(0)->shouldBeCalledOnce();
        $collator->__invoke(0)->willReturn(1);

        $job = new CollateAddressWithReferenceOrPostalCodeCronJob($clock, $collator->reveal());

        $actual = $job->run(['last-max-id' => 0]);
        self::assertEquals(['last-max-id' => 1], $actual);
    }
}
