from functools import wraps

from flask import abort
from flask_login import current_user, login_required


def roles_required(*role_codes):
    """Require the logged-in user to have at least one of the supplied roles."""
    allowed = set(role_codes)

    def decorator(view_func):
        @wraps(view_func)
        @login_required
        def wrapped(*args, **kwargs):
            user_roles = {role.code for role in current_user.roles}
            if not user_roles.intersection(allowed):
                abort(403)
            return view_func(*args, **kwargs)

        return wrapped

    return decorator


def permission_required(permission_code):
    """Require a specific permission through any role assigned to the user."""
    def decorator(view_func):
        @wraps(view_func)
        @login_required
        def wrapped(*args, **kwargs):
            if not current_user.has_permission(permission_code):
                abort(403)
            return view_func(*args, **kwargs)

        return wrapped

    return decorator
