# coding=utf8
import json

from core.utils import log as logging
from rest_framework.views import exception_handler
import traceback
from rest_framework import exceptions
from django.utils.encoding import smart_text
from django.http.response import Http404
from django.core.exceptions import ObjectDoesNotExist

from . import errcode
from .exceptions import CustomAPIException, ManageAPIException
from .response import APIResponse, MangeAPIResponse


def custom_exception_handler(exc, context):
    # Call REST framework's default exception handler first,
    # to get the standard error response.
    #     response = exception_handler(exc, context)

    if isinstance(exc, CustomAPIException):
        response = APIResponse(errcode=exc.errcode, errmsg=exc.errmsg)
    elif isinstance(exc, exceptions.Throttled):
        response = APIResponse(errcode=errcode.ERRCODE_THROTTLED, errmsg=u'请求过于频繁,请稍后再试!')
    elif isinstance(exc, ManageAPIException):
        response = MangeAPIResponse(errcode=exc.errcode, errmsg=exc.errmsg)
    elif isinstance(exc, exceptions.ValidationError):
        if isinstance(exc.detail, list):
            detail = exc.detail[1]
        elif isinstance(exc.detail, dict):
            detail = exc.detail
        else:
            detail = smart_text(exc.detail)
        response = APIResponse(errcode=errcode.ERRCODE_PARAM_ERROR, detail=detail)
    elif isinstance(exc, exceptions.APIException):
        response = APIResponse(errcode=exc.status_code, errmsg=smart_text(exc))
    elif isinstance(exc, (Http404, ObjectDoesNotExist)):
        if isinstance(exc.args, (list, dict)):
            detail = json.dumps(exc.args, ensure_ascii=False)
        else:
            detail = smart_text(exc.args)
        response = APIResponse(errcode=404, detail=detail)
    else:
        response = exception_handler(exc, context)

    trace = traceback.format_exc()
    api_request = context.get('request', None)
    request = api_request._request if api_request and hasattr(api_request, '_request') else None
    logging.error(trace, exc_info=True, extra={'request': request, })
    if not response:
        response = APIResponse(errcode=-1)
    # logging.error(context['request'].body)

    return response
