from django.core.exceptions import PermissionDenied
from .models import Case, CaseCollection, Series


def user_is_author_or_atlas_series_checker_or_atlas_marker_or_open_access(function):
    def wrap(request, *args, **kwargs):
        series = Series.objects.get(pk=kwargs["pk"])
        if (
            request.user in series.get_author_objects()
            or series.open_access
            or request.user.groups.filter(name="atlas_editor").exists()
            or request.user.groups.filter(name="atlas_marker").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


def user_is_author_or_atlas_series_checker(function):
    def wrap(request, *args, **kwargs):
        series = Series.objects.get(pk=kwargs["pk"])
        if (
            request.user in series.get_author_objects()
            or request.user.groups.filter(name="atlas_editor").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


def user_has_case_view_access(function):
    def wrap(request, *args, **kwargs):
        atlas = Case.objects.get(pk=kwargs["pk"])

        # If open access everyone can view
        if atlas.open_access:
            return function(request, *args, **kwargs)
        if (
            request.user in atlas.author.all()
            or request.user.groups.filter(name="atlas_editor").exists()
            or request.user.groups.filter(name="atlas_marker").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


def user_is_author_or_atlas_editor(function):
    def wrap(request, *args, **kwargs):
        atlas = Case.objects.get(pk=kwargs["pk"])
        if (
            request.user in atlas.author.all()
            or request.user.groups.filter(name="atlas_editor").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap

def user_is_collection_author_or_atlas_editor(function):
    def wrap(request, *args, **kwargs):
        if "exam_id" in kwargs:
            atlas = CaseCollection.objects.get(pk=kwargs["exam_id"])
        elif "collection_id" in kwargs:
            atlas = CaseCollection.objects.get(pk=kwargs["collection_id"])
        else:
            atlas = CaseCollection.objects.get(pk=kwargs["pk"])
        if (
            request.user in atlas.author.all()
            or request.user.groups.filter(name="atlas_editor").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


def user_is_atlas_editor(function):
    def wrap(request, *args, **kwargs):
        if (
            request.user.groups.filter(name="atlas_editor").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap


def user_is_atlas_marker(function):
    def wrap(request, *args, **kwargs):
        if (
            request.user.groups.filter(name="atlas_marker").exists()
            or request.user.is_superuser
        ):
            return function(request, *args, **kwargs)
        else:
            raise PermissionDenied

    wrap.__doc__ = function.__doc__
    wrap.__name__ = function.__name__
    return wrap
