from functools import wraps

from django.core.exceptions import PermissionDenied
from django.shortcuts import redirect


def role_required(*roles):
    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated:
                return redirect(f'/accounts/login/?next={request.path}')
            if not request.user.has_role(*roles):
                raise PermissionDenied
            return view_func(request, *args, **kwargs)

        return wrapper

    return decorator


def capability_required(*capabilities, any_of=False):
    """
    Enforce one or more capabilities from the RBAC matrix.
    By default all listed capabilities are required.
    """

    def decorator(view_func):
        @wraps(view_func)
        def wrapper(request, *args, **kwargs):
            if not request.user.is_authenticated:
                return redirect(f'/accounts/login/?next={request.path}')

            if any_of:
                allowed = request.user.has_any_capability(*capabilities)
            else:
                allowed = all(
                    request.user.has_capability(capability)
                    for capability in capabilities
                )

            if not allowed:
                raise PermissionDenied
            return view_func(request, *args, **kwargs)

        return wrapper

    return decorator
