from graphene_django.filter import DjangoFilterConnectionField
from graphene_permissions.permissions import AllowAny


class AuthNode:
    permission_classes = (AllowAny,)

    @classmethod
    def get_node(cls, info, id):
        if all([perm().has_node_permission(info, id) for perm in cls.permission_classes]):
            try:
                object_instance = cls._meta.model.objects.get(id=id)
            except cls._meta.model.DoesNotExist:
                object_instance = None
            return object_instance
        else:
            return None


class AuthMutation:
    permission_classes = (AllowAny,)

    @classmethod
    def has_permission(cls, root, info, input):
        return all(
            [perm().has_mutation_permission(root, info, input) for perm in cls.permission_classes]
        )


class AuthFilter(DjangoFilterConnectionField):
    """
    Custom ConnectionField for basic authentication system.
    """
    permission_classes = (AllowAny,)

    @classmethod
    def has_permission(cls, info):
        return all(
            [perm().has_filter_permission(info) for perm in cls.permission_classes]
        )

    @classmethod
    def connection_resolver(
            cls, resolver, connection, default_manager, max_limit,
            enforce_first_or_last, filterset_class, filtering_args,
            root, info, **args
    ):

        filter_kwargs = {k: v for k, v in args.items() if k in filtering_args}
        qs = filterset_class(
            data=filter_kwargs,
            queryset=default_manager.get_queryset()
        ).qs

        if not cls.has_permission(info):
            return super(DjangoFilterConnectionField, cls).connection_resolver(
                resolver, connection, qs.none(),
                max_limit, enforce_first_or_last, root, info, **args
            )

        return super(DjangoFilterConnectionField, cls).connection_resolver(
            resolver, connection, qs, max_limit, enforce_first_or_last,
            filterset_class, filtering_args, **args,
        )
