<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CoreBundle\Tests\ApplicationSystem;

use Ferienpass\CoreBundle\ApplicationSystem\FirstComeApplicationSystem;
use Ferienpass\CoreBundle\ApplicationSystem\LotApplicationSystem;
use Ferienpass\CoreBundle\Fixtures\Factory\EditionTaskFactory;
use PHPUnit\Framework\TestCase;
use Zenstruck\Foundry\Test\Factories;

final class AbstractApplicationSystemTest extends TestCase
{
    use Factories;

    public function testWithTaskThrowsWhenTaskIsNotAnApplicationSystem(): void
    {
        $task = EditionTaskFactory::new()->ofTypeHostEditingStage()->create();

        $this->expectException(\InvalidArgumentException::class);

        new FirstComeApplicationSystem()->withTask($task);
    }

    public function testWithTaskThrowsWhenApplicationSystemTypeMismatch(): void
    {
        $lotTask = EditionTaskFactory::new()->ofTypeLotApplicationSystem()->create();

        $this->expectException(\InvalidArgumentException::class);

        new FirstComeApplicationSystem()->withTask($lotTask);
    }

    public function testWithTaskReturnsNewInstanceAndDoesNotMutate(): void
    {
        $task = EditionTaskFactory::new()->ofTypeFirstComeApplicationSystem()->create();

        $original = new FirstComeApplicationSystem();
        $withTask = $original->withTask($task);

        self::assertNotSame($original, $withTask);
        self::assertNull($original->getTask());
        self::assertSame($task, $withTask->getTask());
    }

    public function testWithTaskWorksForLotSystem(): void
    {
        $task = EditionTaskFactory::new()->ofTypeLotApplicationSystem()->create();

        $system = new LotApplicationSystem()->withTask($task);

        self::assertSame($task, $system->getTask());
    }

    public function testSuggestTransitionSetsTaskOnAttendance(): void
    {
        $task = EditionTaskFactory::new()->ofTypeFirstComeApplicationSystem()->create();
        $system = new FirstComeApplicationSystem()->withTask($task);

        $attendance = new \Ferienpass\CoreBundle\Entity\Attendance(
            new \Ferienpass\CoreBundle\Entity\Offer\Base(),
            new \Ferienpass\CoreBundle\Entity\Participant\BaseParticipant()
        );

        self::assertNull($attendance->getTask());

        $system->suggestTransition($attendance);

        self::assertSame($task, $attendance->getTask());
    }
}
