from .views import APIView
from .generics import GenericAPIView
from . import mixins


class ViewSetMixin:
    """
    Overrides ``.as_view()`` so that it takes an ``actions_map`` keyword that performs
    the binding of HTTP methods to actions on the view.

    For example, to create a concrete view binding the 'GET' and 'POST' methods
    to the 'list' and 'create' actions...

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    """

    @classmethod
    def as_view(cls, action_map=None, **initkwargs):
        """
        Allows custom request to method routing based on given ``action_map`` kwarg.
        """

        # Needs to re-implement the method but contains all the things the parent does.
        if not action_map:  # actions must not be empty
            raise TypeError("action_map is a required argument.")

        def view(request):
            self = cls(**initkwargs)
            self.request = request
            self.lookup_url_kwargs = self.request.matchdict
            self.action_map = action_map
            self.action = self.action_map.get(self.request.method.lower())

            for method, action in action_map.items():
                handler = getattr(self, action)
                setattr(self, method, handler)

            return self.dispatch(self.request, **self.request.matchdict)

        return view


class APIViewSet(ViewSetMixin, APIView):
    """
    Does not provide any actions by default.
    """

    pass


class GenericAPIViewSet(ViewSetMixin, GenericAPIView):
    """
    The GenericAPIView class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the ``get_object`` and ``get_query`` methods.
    """

    pass


class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericAPIViewSet):
    """
    A ViewSet that provides default ``list()`` and ``retrieve()`` actions.
    """

    pass


class ModelCRUDViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericAPIViewSet):
    """
    A ViewSet that provides default ``create()``, ``retrieve()``, ``update()``, ``destroy()`` and ``list()`` actions.
    """

    pass


class ModelCRPDViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.PartialUpdateMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericAPIViewSet):
    """
    A ViewSet that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``destroy()``
    and ``list()`` actions.
    """

    pass


class ModelCRUPDViewSet(mixins.CreateModelMixin,
                        mixins.RetrieveModelMixin,
                        mixins.UpdateModelMixin,
                        mixins.PartialUpdateMixin,
                        mixins.DestroyModelMixin,
                        mixins.ListModelMixin,
                        GenericAPIViewSet):
    """
    A viewset that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``'update()``,
    ``destroy()`` and ``list()`` actions.
    """

    pass

from .views import APIView
from .generics import GenericAPIView
from . import mixins


class ViewSetMixin:
    """
    Overrides ``.as_view()`` so that it takes an ``actions_map`` keyword that performs
    the binding of HTTP methods to actions on the view.

    For example, to create a concrete view binding the 'GET' and 'POST' methods
    to the 'list' and 'create' actions...

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    """

    @classmethod
    def as_view(cls, action_map=None, **initkwargs):
        """
        Allows custom request to method routing based on given ``action_map`` kwarg.
        """

        # Needs to re-implement the method but contains all the things the parent does.
        if not action_map:  # actions must not be empty
            raise TypeError("action_map is a required argument.")

        def view(request):
            self = cls(**initkwargs)
            self.request = request
            self.lookup_url_kwargs = self.request.matchdict
            self.action_map = action_map
            self.action = self.action_map.get(self.request.method.lower())

            for method, action in action_map.items():
                handler = getattr(self, action)
                setattr(self, method, handler)

            return self.dispatch(self.request, **self.request.matchdict)

        return view


class APIViewSet(ViewSetMixin, APIView):
    """
    Does not provide any actions by default.
    """

    pass


class GenericAPIViewSet(ViewSetMixin, GenericAPIView):
    """
    The GenericAPIView class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the ``get_object`` and ``get_query`` methods.
    """

    pass


class ReadOnlyModelViewSet(mixins.RetrieveModelMixin,
                           mixins.ListModelMixin,
                           GenericAPIViewSet):
    """
    A ViewSet that provides default ``list()`` and ``retrieve()`` actions.
    """

    pass


class ModelCRUDViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.UpdateModelMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericAPIViewSet):
    """
    A ViewSet that provides default ``create()``, ``retrieve()``, ``update()``, ``destroy()`` and ``list()`` actions.
    """

    pass


class ModelCRPDViewSet(mixins.CreateModelMixin,
                       mixins.RetrieveModelMixin,
                       mixins.PartialUpdateMixin,
                       mixins.DestroyModelMixin,
                       mixins.ListModelMixin,
                       GenericAPIViewSet):
    """
    A ViewSet that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``destroy()``
    and ``list()`` actions.
    """

    pass


class ModelCRUPDViewSet(mixins.CreateModelMixin,
                        mixins.RetrieveModelMixin,
                        mixins.UpdateModelMixin,
                        mixins.PartialUpdateMixin,
                        mixins.DestroyModelMixin,
                        mixins.ListModelMixin,
                        GenericAPIViewSet):
    """
    A viewset that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``'update()``,
    ``destroy()`` and ``list()`` actions.
    """

    pass

Overrides ``.as_view()`` so that it takes an ``actions_map`` keyword that performs     the binding of HTTP methods to actions on the view.      For example, to create a concrete view binding the 'GET' and 'POST' methods     to the 'list' and 'create' actions...      view = MyViewSet.as_view({'get': 'list', 'post': 'create'}) Allows custom request to method routing based on given ``action_map`` kwarg. # Needs to re-implement the method but contains all the things the parent does. # actions must not be empty Does not provide any actions by default. The GenericAPIView class does not provide any actions by default,     but does include the base set of generic view behavior, such as     the ``get_object`` and ``get_query`` methods. A ViewSet that provides default ``list()`` and ``retrieve()`` actions. A ViewSet that provides default ``create()``, ``retrieve()``, ``update()``, ``destroy()`` and ``list()`` actions. A ViewSet that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``destroy()``     and ``list()`` actions. A viewset that provides default ``create()``, ``retrieve()``, ``partial_update()``, ``'update()``,     ``destroy()`` and ``list()`` actions.