import gzip
import logging
from typing import Dict, Tuple, Optional

from httpclient import HttpRequest
from httpmessagehandler import HttpMessageHandler

from ._KongRequest import KongRequest
from ._LambdaResponse import LambdaResponse

logger = logging.getLogger("konglambdamessagehandler")

_DEFAULT_COMPRESSION_THRESHOLD_BYTES = 1024 * 1024  # 1MB


class KongLambdaMessageHandler:

    def __init__(
        self,
        http_message_handler: HttpMessageHandler,
        compression_threshold: Optional[int] = None,
    ) -> None:
        self.http_message_handler = http_message_handler
        self.compression_threshold = compression_threshold or _DEFAULT_COMPRESSION_THRESHOLD_BYTES

    def handle_messages(self, event: Dict) -> Dict:
        http_request = self._parse_http_request(event)
        http_response = self.http_message_handler.handle_request(request=http_request)
        body, headers = self._compress_body(
            body=http_response.body,
            headers=http_response.headers
        )
        response = LambdaResponse(
            status=http_response.status_code,
            response=body,
            headers=headers,
        )
        return response.response

    @staticmethod
    def _parse_http_request(event):
        request = KongRequest(event)
        http_request = HttpRequest(
            url=request.path,
            method=request.method,
            query=request.args,
            headers=request.headers,
            body=request.data,
        )
        return http_request

    def _compress_body(self, body: bytes, headers: Dict[str, str]) -> Tuple[bytes, dict]:
        if "Content-Encoding" not in headers and len(body) > self.compression_threshold:
            logger.info("Body size %s > %s, compressing.", len(body), self.compression_threshold)
            body = gzip.compress(data=body)
            logger.info("Compressed body size %s", len(body))
            headers["Content-Encoding"] = "gzip"
        return body, headers
