<?php

declare(strict_types=1);

namespace App\Tests\Functional\Module\Core;

use App\Module\Core\Application\Rbac\RbacSeeder;
use App\Module\Core\Domain\Entity\User;
use App\Module\Core\Domain\Security\SystemRoles;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Console\Application;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
use Symfony\Component\Console\Tester\CommandTester;

use function array_map;
use function uniqid;

/**
 * @internal
 */
final class AssignDefaultRolesCommandTest extends KernelTestCase
{
    public function testBackfillLinksUsersMissingTheUserRole(): void
    {
        $kernel = self::bootKernel();
        $em     = self::getContainer()->get(EntityManagerInterface::class);
        self::getContainer()->get(RbacSeeder::class)->ensureSystemRoles();

        // Crée un user puis simule l'état « legacy » (aucun rôle RBAC) en retirant
        // le rôle « user » auto-assigné à la création.
        $user = new User();
        $user->setUsername('backfill-'.uniqid());
        $user->setPassword('x');
        $em->persist($user);
        $em->flush();
        foreach ($user->getRbacRoles()->toArray() as $role) {
            $user->removeRbacRole($role);
        }
        $em->flush();
        $id = $user->getId();
        $em->clear();

        $before = $em->getRepository(User::class)->find($id);
        self::assertInstanceOf(User::class, $before);
        self::assertCount(0, $before->getRbacRoles(), 'Précondition : le user ne doit avoir aucun rôle RBAC.');
        $em->clear();

        $tester = new CommandTester(new Application($kernel)->find('app:assign-default-roles'));
        $tester->execute([]);
        $tester->assertCommandIsSuccessful();

        $em->clear();
        $after = $em->getRepository(User::class)->find($id);
        self::assertInstanceOf(User::class, $after);
        $codes = array_map(static fn ($role) => $role->getCode(), $after->getRbacRoles()->toArray());
        self::assertContains(SystemRoles::USER_CODE, $codes, 'Le backfill doit rattacher le rôle « user ».');
    }
}
