<gh_stars>0
from django.core.exceptions import PermissionDenied

from rest_framework import viewsets, mixins
from rest_framework.decorators import action
from rest_framework.response import Response

from emstrack.mixins import UpdateModelUpdateByMixin, BasePermissionMixin
from equipment.models import EquipmentItem, EquipmentHolder, Equipment
from equipment.serializers import EquipmentItemSerializer, EquipmentSerializer
from hospital.viewsets import logger
from login.permissions import get_permissions


class EquipmentItemViewSet(mixins.ListModelMixin,
                           mixins.RetrieveModelMixin,
                           UpdateModelUpdateByMixin,
                           viewsets.GenericViewSet):
    """
    API endpoint for manipulating hospital equipment.

    list:
    Retrieve list of hospital equipment.

    retrieve:
    Retrieve an existing hospital equipment instance.

    update:
    Update existing hospital equipment instance.

    partial_update:
    Partially update existing hospital equipment instance.
    """

    queryset = EquipmentItem.objects.all()

    serializer_class = EquipmentItemSerializer
    lookup_field = 'equipment_id'

    # make sure both fields are looked up
    def get_queryset(self):

        # retrieve user
        user = self.request.user

        # return nothing if anonymous
        if user.is_anonymous:
            raise PermissionDenied()
        
        # retrieve id
        equipmentholder_id = int(self.kwargs['equipmentholder_id'])
        logger.debug('kwargs = {}'.format(self.kwargs))

        try:
            
            # retrieve equipmentholder
            equipmentholder = EquipmentHolder.objects.get(id=equipmentholder_id)

            # read or write?
            if self.request.method == 'GET':
                is_write = False
            elif (self.request.method == 'PUT' or
                  self.request.method == 'PATCH' or
                  self.request.method == 'DELETE'):
                is_write = True

            # is hospital?
            if equipmentholder.is_hospital():

                # check permission (and also existence)
                if is_write:
                    if not get_permissions(user).check_can_write(hospital=equipmentholder.hospital.id):
                        raise PermissionDenied()
                else:
                    if not get_permissions(user).check_can_read(hospital=equipmentholder.hospital.id):
                        raise PermissionDenied()

            # is ambulance?
            elif equipmentholder.is_ambulance():

                # check permission (and also existence)
                if is_write:
                    if not get_permissions(user).check_can_write(ambulance=equipmentholder.ambulance.id):
                        raise PermissionDenied()
                else:
                    if not get_permissions(user).check_can_read(ambulance=equipmentholder.ambulance.id):
                        raise PermissionDenied()

            else:
                raise PermissionDenied()

        except EquipmentHolder.DoesNotExist as e:
            raise PermissionDenied()

        # build queryset
        filter = {'equipmentholder_id': equipmentholder_id}
        return self.queryset.filter(**filter)


class EquipmentViewSet(BasePermissionMixin,
                       viewsets.GenericViewSet):
    """
    API endpoint for manipulating equipment.

    metadata
    Partially update existing hospital instance.
    """

    profile_field = 'equipments'
    filter_field = 'id'
    queryset = EquipmentHolder.objects.all()

    @action(detail=True)
    def metadata(self, request, pk=None, **kwargs):
        """
        Retrive hospital equipment metadata.
        """

        equipmentholder = self.get_object()
        equipment_list = equipmentholder.equipmentitem_set.values('equipment')
        equipment = Equipment.objects.filter(id__in=equipment_list)
        serializer = EquipmentSerializer(equipment, many=True)
        return Response(serializer.data)

from django.core.exceptions import PermissionDenied

from rest_framework import viewsets, mixins
from rest_framework.decorators import action
from rest_framework.response import Response

from emstrack.mixins import UpdateModelUpdateByMixin, BasePermissionMixin
from equipment.models import EquipmentItem, EquipmentHolder, Equipment
from equipment.serializers import EquipmentItemSerializer, EquipmentSerializer
from hospital.viewsets import logger
from login.permissions import get_permissions


class EquipmentItemViewSet(mixins.ListModelMixin,
                           mixins.RetrieveModelMixin,
                           UpdateModelUpdateByMixin,
                           viewsets.GenericViewSet):
    """
    API endpoint for manipulating hospital equipment.

    list:
    Retrieve list of hospital equipment.

    retrieve:
    Retrieve an existing hospital equipment instance.

    update:
    Update existing hospital equipment instance.

    partial_update:
    Partially update existing hospital equipment instance.
    """

    queryset = EquipmentItem.objects.all()

    serializer_class = EquipmentItemSerializer
    lookup_field = 'equipment_id'

    # make sure both fields are looked up
    def get_queryset(self):

        # retrieve user
        user = self.request.user

        # return nothing if anonymous
        if user.is_anonymous:
            raise PermissionDenied()
        
        # retrieve id
        equipmentholder_id = int(self.kwargs['equipmentholder_id'])
        logger.debug('kwargs = {}'.format(self.kwargs))

        try:
            
            # retrieve equipmentholder
            equipmentholder = EquipmentHolder.objects.get(id=equipmentholder_id)

            # read or write?
            if self.request.method == 'GET':
                is_write = False
            elif (self.request.method == 'PUT' or
                  self.request.method == 'PATCH' or
                  self.request.method == 'DELETE'):
                is_write = True

            # is hospital?
            if equipmentholder.is_hospital():

                # check permission (and also existence)
                if is_write:
                    if not get_permissions(user).check_can_write(hospital=equipmentholder.hospital.id):
                        raise PermissionDenied()
                else:
                    if not get_permissions(user).check_can_read(hospital=equipmentholder.hospital.id):
                        raise PermissionDenied()

            # is ambulance?
            elif equipmentholder.is_ambulance():

                # check permission (and also existence)
                if is_write:
                    if not get_permissions(user).check_can_write(ambulance=equipmentholder.ambulance.id):
                        raise PermissionDenied()
                else:
                    if not get_permissions(user).check_can_read(ambulance=equipmentholder.ambulance.id):
                        raise PermissionDenied()

            else:
                raise PermissionDenied()

        except EquipmentHolder.DoesNotExist as e:
            raise PermissionDenied()

        # build queryset
        filter = {'equipmentholder_id': equipmentholder_id}
        return self.queryset.filter(**filter)


class EquipmentViewSet(BasePermissionMixin,
                       viewsets.GenericViewSet):
    """
    API endpoint for manipulating equipment.

    metadata
    Partially update existing hospital instance.
    """

    profile_field = 'equipments'
    filter_field = 'id'
    queryset = EquipmentHolder.objects.all()

    @action(detail=True)
    def metadata(self, request, pk=None, **kwargs):
        """
        Retrive hospital equipment metadata.
        """

        equipmentholder = self.get_object()
        equipment_list = equipmentholder.equipmentitem_set.values('equipment')
        equipment = Equipment.objects.filter(id__in=equipment_list)
        serializer = EquipmentSerializer(equipment, many=True)
        return Response(serializer.data)
API endpoint for manipulating hospital equipment.      list:     Retrieve list of hospital equipment.      retrieve:     Retrieve an existing hospital equipment instance.      update:     Update existing hospital equipment instance.      partial_update:     Partially update existing hospital equipment instance. # make sure both fields are looked up # retrieve user # return nothing if anonymous # retrieve id # retrieve equipmentholder # read or write? # is hospital? # check permission (and also existence) # is ambulance? # check permission (and also existence) # build queryset API endpoint for manipulating equipment.      metadata     Partially update existing hospital instance. Retrive hospital equipment metadata.