<?php

declare(strict_types=1);

namespace App\Tests\Module\Commercial\Unit;

use ApiPlatform\State\SerializerContextBuilderInterface;
use App\Module\Commercial\Domain\Entity\Client;
use App\Module\Commercial\Infrastructure\ApiPlatform\Serializer\ClientReadGroupContextBuilder;
use PHPUnit\Framework\TestCase;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\HttpFoundation\Request;

/**
 * Tests unitaires du context builder qui ajoute conditionnellement le groupe
 * de lecture `client:read:accounting` selon la permission accounting.view
 * (§ 2.7 / § 4.1 / § 4.2).
 *
 * @internal
 */
final class ClientReadGroupContextBuilderTest extends TestCase
{
    public function testAddsAccountingGroupForClientReadWhenGranted(): void
    {
        $builder = $this->builder(
            baseContext: ['resource_class' => Client::class, 'groups' => ['client:read', 'default:read']],
            granted: true,
        );

        $context = $builder->createFromRequest(new Request(), true);

        self::assertContains('client:read:accounting', $context['groups']);
    }

    public function testDoesNotAddAccountingGroupWhenNotGranted(): void
    {
        $builder = $this->builder(
            baseContext: ['resource_class' => Client::class, 'groups' => ['client:read', 'default:read']],
            granted: false,
        );

        $context = $builder->createFromRequest(new Request(), true);

        self::assertNotContains('client:read:accounting', $context['groups']);
    }

    public function testDoesNotAddAccountingGroupOnWrite(): void
    {
        $builder = $this->builder(
            baseContext: ['resource_class' => Client::class, 'groups' => ['client:write:main']],
            granted: true,
        );

        // normalization = false -> ecriture : pas de groupe de lecture ajoute.
        $context = $builder->createFromRequest(new Request(), false);

        self::assertNotContains('client:read:accounting', $context['groups']);
    }

    public function testIgnoresOtherResources(): void
    {
        $builder = $this->builder(
            baseContext: ['resource_class' => 'App\Other\Resource', 'groups' => ['other:read']],
            granted: true,
        );

        $context = $builder->createFromRequest(new Request(), true);

        self::assertSame(['other:read'], $context['groups']);
    }

    /**
     * @param array<string, mixed> $baseContext
     */
    private function builder(array $baseContext, bool $granted): ClientReadGroupContextBuilder
    {
        $decorated = $this->createStub(SerializerContextBuilderInterface::class);
        $decorated->method('createFromRequest')->willReturn($baseContext);

        $security = $this->createStub(Security::class);
        $security->method('isGranted')->willReturn($granted);

        return new ClientReadGroupContextBuilder($decorated, $security);
    }
}
