# coding=utf-8
import logging
from django.conf import settings
from django.conf.urls import url, include
from django.core.exceptions import PermissionDenied
from django.http import HttpResponse, Http404
from django.utils.functional import cached_property
from django.views.decorators.csrf import csrf_exempt
import sys
from odin.codecs import json_codec
from odin.exceptions import ValidationError, CodecDecodeError
from baldr import content_type_resolvers
from baldr.exceptions import ImmediateErrorHttpResponse, ImmediateHttpResponse
from baldr.resources import Error, Listing


CODECS = {json_codec.CONTENT_TYPE: json_codec}
# Attempt to load other codecs that have dependencies
try:
    from odin.codecs import msgpack_codec
except ImportError:
    pass
else:
    CODECS[msgpack_codec.CONTENT_TYPE] = msgpack_codec

logger = logging.getLogger('baldr.request')


class ResourceApiCommon(object):
    # The resource this API is modelled on.
    resource = None
    resource_id_regex = r'\d+'

    # Handlers used to resolve the request content-type of the request body.
    # These are checked in the order defined until one returns a content-type.
    request_type_resolvers = [
        content_type_resolvers.content_type_header(),
        content_type_resolvers.accepts_header(),
        content_type_resolvers.settings_default(),
    ]

    # Handlers used to resolve the response content-type.
    # These are checked in the order defined until one returns a content-type.
    response_type_resolvers = [
        content_type_resolvers.accepts_header(),
        content_type_resolvers.content_type_header(),
        content_type_resolvers.settings_default(),
    ]

    # Codecs that are supported for Encoding/Decoding resources.
    registered_codecs = CODECS
    url_prefix = r''

    def __init__(self, api_name=None):
        if api_name:
            self.api_name = api_name
        elif not hasattr(self, 'api_name'):
            self.api_name = "%ss" % self.resource._meta.name

    def url(self, regex, view, kwargs=None, name=None, prefix=''):
        """
        Behaves like the django built in ``url`` method but constrains the URL to the API name.

        :param regex: This should be a part regex that applies only to the targeted method ie::

            self.url("(\d+)", ...)
        """
        if regex:
            return url(r'^%s/%s/?$' % (self.url_prefix + self.api_name.lower(), regex), view, kwargs, name, prefix)
        else:
            return url(r'^%s/?$' % (self.url_prefix + self.api_name.lower()), view, kwargs, name, prefix)

    @property
    def urls(self):
        """
        Return url conf for resource object.
        """
        return self.base_urls()

    def resolve_request_type(self, request):