from rest_framework import exceptions, serializers
from core.models import ResourceRequest, Allocation, Quota, Identity, AtmosphereUser as User
from core.models.status_type import StatusType
from api.v2.serializers.summaries import (
    AllocationSummarySerializer,
    IdentitySummarySerializer,
    UserSummarySerializer,
    ProviderSummarySerializer,
    QuotaSummarySerializer,
    StatusTypeSummarySerializer
)


class UserRelatedField(serializers.PrimaryKeyRelatedField):

    def get_queryset(self):
        return User.objects.all()

    def to_representation(self, value):
        user = User.objects.get(pk=value.pk)
        serializer = UserSummarySerializer(user, context=self.context)
        return serializer.data


class IdentityRelatedField(serializers.RelatedField):

    def get_queryset(self):
        return Identity.objects.all()

    def to_representation(self, value):
        identity = Identity.objects.get(pk=value.pk)
        serializer = IdentitySummarySerializer(identity, context=self.context)
        return serializer.data

    def to_internal_value(self, data):
        queryset = self.get_queryset()
        if isinstance(data, dict):
            identity = data.get("id", None)
        else:
            identity = data
        try:
            return queryset.get(id=identity)
        except:
            raise exceptions.ValidationError(
                "Identity with id '%s' does not exist."
                % identity
            )


class AllocationRelatedField(serializers.RelatedField):

    def get_queryset(self):
        return Allocation.objects.all()

    def to_representation(self, value):
        if value.pk is None:
            return None

        allocation = Allocation.objects.get(pk=value.pk)
        serializer = AllocationSummarySerializer(allocation, context=self.context)
        return serializer.data

    def to_internal_value(self, data):
        queryset = self.get_queryset()
        if isinstance(data, dict):
            identity = data.get("id", None)
        else:
            identity = data
        try:
            return queryset.get(id=identity)
        except:
            raise exceptions.ValidationError(
                "Allocation with id '%s' does not exist."
                % identity
            )


class QuotaRelatedField(serializers.RelatedField):

    def get_queryset(self):
        return Quota.objects.all()

    def to_representation(self, value):
        if value.pk is None:
            return None

        quota = Quota.objects.get(pk=value.pk)
        serializer = QuotaSummarySerializer(quota, context=self.context)
        return serializer.data

    def to_internal_value(self, data):
        queryset = self.get_queryset()
        if isinstance(data, dict):
            identity = data.get("id", None)
        else:
            identity = data
        try:
            return queryset.get(id=identity)
        except:
            raise exceptions.ValidationError(
                "Quota with id '%s' does not exist."
                % identity
            )


class StatusTypeRelatedField(serializers.RelatedField):

    def get_queryset(self):
        return StatusType.objects.all()

    def to_representation(self, value):
        status_type = StatusType.objects.get(pk=value.pk)
        serializer = StatusTypeSummarySerializer(status_type, context=self.context)
        return serializer.data

    def to_internal_value(self, data):
        queryset = self.get_queryset()
        if isinstance(data, dict):
            identity = data.get("id", None)
        else:
            identity = data

        try:
            return queryset.get(id=identity)
        except:
            raise exceptions.ValidationError(
                "StatusType with id '%s' does not exist."
                % identity
            )


class ResourceRequestSerializer(serializers.HyperlinkedModelSerializer):
    uuid = serializers.CharField(read_only=True)
    created_by = UserRelatedField(read_only=True)
    user = UserSummarySerializer(source='membership.identity.created_by', read_only=True)
    identity = IdentityRelatedField(source='membership.identity',
                                    queryset=Identity.objects.none())
    provider = ProviderSummarySerializer(source='membership.identity.provider', read_only=True)
    status = StatusTypeRelatedField(queryset=StatusType.objects.none(),
                                    allow_null=True,
                                    required=False)
    quota = QuotaRelatedField(queryset=Quota.objects.all(),
                              allow_null=True,
                              required=False)

    allocation = AllocationRelatedField(queryset=Allocation.objects.all(),
                                        allow_null=True,
                                        required=False)
    class Meta:
        model = ResourceRequest
        view_name = 'api:v2:resourcerequest-detail'
        fields = (
            'id',
            'uuid',
            'url',
            'request',
            'description',
            'status',
            'created_by',
            'user',
            'identity',
            'provider',
            'admin_message',
            'quota',
            'allocation'
        )


class UserResourceRequestSerializer(serializers.HyperlinkedModelSerializer):
    quota = QuotaRelatedField(read_only=True)
    allocation = AllocationRelatedField(read_only=True)
    status = StatusTypeRelatedField(read_only=True)
    admin_message = serializers.CharField(read_only=True)
    uuid = serializers.CharField(read_only=True)
    created_by = UserRelatedField(read_only=True)
    user = UserSummarySerializer(source='membership.identity.created_by', read_only=True)
    identity = IdentityRelatedField(source='membership.identity',
                                    queryset=Identity.objects.none())
    provider = ProviderSummarySerializer(source='membership.identity.provider', read_only=True)

    class Meta:
        model = ResourceRequest
        view_name = 'api:v2:resourcerequest-detail'
        fields = (
            'id',
            'uuid',
            'url',
            'request',
            'description',
            'status',
            'created_by',
            'user',
            'identity',
            'provider',
            'admin_message',
            'quota',
            'allocation'
        )

@@ -136,16 +136,36 @@
  as User
+, IdentityMembership
 %0Afrom co
@@ -432,17 +432,16 @@
 izer%0A)%0A%0A
-%0A
 class Us
@@ -791,33 +791,32 @@
 .RelatedField):%0A
-%0A
     def get_quer
@@ -4847,24 +4847,484 @@
 ired=False)%0A
+    current_quota = serializers.SerializerMethodField()%0A    current_allocation = serializers.SerializerMethodField()%0A%0A    def get_current_quota(self, request):%0A        user_membership = IdentityMembership.objects.get(id=request.membership_id)%0A        return user_membership.quota.id%0A%0A    def get_current_allocation(self, request):%0A        user_membership = IdentityMembership.objects.get(id=request.membership_id)%0A        return user_membership.allocation.id%0A%0A
     class Me
@@ -5719,32 +5719,95 @@
     'allocation'
+,%0A            'current_quota',%0A            'current_allocation'
 %0A        )%0A%0A%0Acla

add "current_allocation" and "current_quota" fields to resource request serializer