<?php

declare(strict_types=1);

namespace App\Tests\Unit\Module\Core\Domain\Entity;

use App\Module\Core\Domain\Entity\Permission;
use App\Module\Core\Domain\Entity\Role;
use App\Module\Core\Domain\Exception\SystemRoleDeletionException;
use InvalidArgumentException;
use PHPUnit\Framework\TestCase;

/**
 * @internal
 */
final class RoleTest extends TestCase
{
    public function testValidConstruction(): void
    {
        $r = new Role('bureau', 'Bureau');
        self::assertSame('bureau', $r->getCode());
        self::assertSame('Bureau', $r->getLabel());
        self::assertFalse($r->isSystem());
        self::assertCount(0, $r->getPermissions());
    }

    public function testCodeMustBeSnakeCase(): void
    {
        $this->expectException(InvalidArgumentException::class);
        new Role('Bureau Commercial', 'x');
    }

    public function testAddRemovePermission(): void
    {
        $r = new Role('bureau', 'Bureau');
        $p = new Permission('core.users.view', 'Voir', 'core');
        $r->addPermission($p);
        self::assertCount(1, $r->getPermissions());
        $r->addPermission($p); // idempotent
        self::assertCount(1, $r->getPermissions());
        $r->removePermission($p);
        self::assertCount(0, $r->getPermissions());
    }

    public function testSystemRoleCannotBeDeleted(): void
    {
        $r = new Role('admin', 'Administrateur', null, true);
        $this->expectException(SystemRoleDeletionException::class);
        $r->ensureDeletable();
    }

    public function testNonSystemRoleIsDeletable(): void
    {
        $r = new Role('bureau', 'Bureau');
        $r->ensureDeletable();
        self::assertFalse($r->isSystem());
    }
}
