import functools
import logging
from inspect import getmembers

from rest_framework import serializers
from rest_framework.reverse import reverse

from .mixins import BridgerSerializerFieldMixin

logger = logging.getLogger(__name__)


def register_resource():
    def decorator(func):
        func._is_additional_resource = True
        return func

    return decorator


def _is_additional_resource(attr):
    return hasattr(attr, "_is_additional_resource")


class AdditionalResourcesField(BridgerSerializerFieldMixin, serializers.ReadOnlyField):

    field_type = "_additional_resources"

    def get_attribute(self, instance):
        return instance

    def to_representation(self, value):
        request = self.parent.context["request"]
        resources = dict()
        for _, function in getmembers(self.parent.__class__, _is_additional_resource):
            _d = function(
                self.parent, instance=value, request=request, user=request.user
            )
            resources = {**resources, **_d}

        return resources


class HyperlinkField(BridgerSerializerFieldMixin, serializers.ReadOnlyField):
    def __init__(self, *args, **kwargs):
        self.reverse_name = kwargs.pop("reverse_name")
        super().__init__(*args, **kwargs)

    def get_attribute(self, obj):
        request = self.context.get("request", None)
        if request:
            return reverse(self.reverse_name, args=[obj.id], request=request)
        return reverse(self.reverse_name, args=[obj.id])
