# coding=utf-8
import json
from logging import Logger

from helper import json_serialize, remove_accents
from requests import Response


class ConfigurationReaderException(Exception):
    pass


class NotFound(Exception):
    pass


class ValidationError(Exception):
    pass


class ResponseError(Exception):
    def __init__(self, logger, response):
        # type: (Logger, Response) -> None

        self.logger = logger
        self.response = response
        self.error_status_code = response.status_code
        self.message = _get_response_content(response)
        response_str = json_serialize(response)

        message = "Unexpected response received. StatusCode: {}; Content: {}; FullResponse:\n{}"
        self.logger.error(message.format(self.error_status_code, self.message, response_str))

        super(ResponseError, self).__init__(self.message)


class NoResponseError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "No response. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(NoResponseError, self).__init__(content)


class ForbiddenError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Forbidden error. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(ForbiddenError, self).__init__(content)


class NotFoundError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Not found. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(NotFoundError, self).__init__(content)


class NotAvailableError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Code not available. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(NotAvailableError, self).__init__(content)


class InUseError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Code in use on another terminal. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(InUseError, self).__init__(content)


class AlreadyUnlockedError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Code already unlocked. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(AlreadyUnlockedError, self).__init__(content)


class ProcessorError(Exception):
    def __init__(self, logger, response):
        self.logger = logger
        self.response = response

        error_status_code = response.status_code
        content = _get_response_content(response)
        message = "Processing error. StatusCode: {}; Content: {}; FullResponse: {}"
        response_str = json_serialize(response)
        self.logger.error(message.format(error_status_code, content, response_str))
        super(ProcessorError, self).__init__(content)


def _get_response_content(response):
    try:
        content = json.loads(response.content).get("detail").encode("utf8")
        return content
    except (AttributeError, ValueError):
        return ""


def build_message_exception(ex):
    error_type = type(ex).__name__
    error_message = ex.message
    error_detail = {"type": error_type, "message": error_message or None}
    ex.message = json.dumps(error_detail)
    return ex
