from requests.exceptions import ConnectionError as RequestConnectionError

from newsreader.news.collection.exceptions import (
    StreamConnectionException,
    StreamDeniedException,
    StreamException,
    StreamForbiddenException,
    StreamNotFoundException,
    StreamTimeOutException,
    StreamTooManyException,
)


class ResponseHandler:
    status_code_mapping = {
        404: StreamNotFoundException,
        401: StreamDeniedException,
        403: StreamForbiddenException,
        408: StreamTimeOutException,
        429: StreamTooManyException,
    }

    exception_mapping = {RequestConnectionError: StreamConnectionException}

    def __enter__(self):
        return self

    def handle_response(self, response):
        status_code = response.status_code

        if status_code in self.status_code_mapping:
            exception = self.status_code_mapping[status_code]
            raise exception(response)

    def map_exception(self, exception):
        if isinstance(exception, StreamException):
            raise exception

        try:
            stream_exception = self.exception_mapping[type(exception)]
        except KeyError:
            stream_exception = StreamException

        message = getattr(exception, "message", str(exception))
        raise stream_exception(
            response=exception.response, message=message
        ) from exception

    def __exit__(self, *args, **kwargs):
        pass
