<?php

declare(strict_types=1);

namespace Fennec\Security;

use Fennec\Http\JsonResponse;
use Fennec\Http\Request;
use Fennec\Middleware\MiddlewareInterface;

/**
 * Vérifie que le rôle attaché à la requête (par AuthenticationMiddleware) satisfait
 * le rôle minimum requis pour la route.
 *
 * Distingue explicitement deux cas : aucune authentification du tout (401) et
 * authentification présente mais rôle insuffisant (403).
 */
final class RoleMiddleware implements MiddlewareInterface
{
    public function __construct(private readonly Role $minimumRequiredRole)
    {
    }

    public function process(Request $request, \Closure $next): JsonResponse
    {
        $roleValue = $request->getAttribute('role');

        if ($roleValue === null) {
            if ($this->minimumRequiredRole === Role::VISITEUR) {
                return $next($request);
            }

            return JsonResponse::error(
                'UNAUTHORIZED',
                'Authentification requise pour accéder à cette ressource.',
                null,
                401,
            );
        }

        $role = \is_string($roleValue) ? Role::tryFrom($roleValue) : null;

        if ($role === null || !$role->satisfies($this->minimumRequiredRole)) {
            return JsonResponse::error(
                'FORBIDDEN',
                'Vous n\'avez pas les droits suffisants pour accéder à cette ressource.',
                null,
                403,
            );
        }

        return $next($request);
    }
}
