from lambdamessagehandler import LambdaAdapter, UnhandledEventException, LambdaEventType
from messagebus import Event, SwaggerMessage
from messageprocessor import ApiRequest
from simplehttprouter import HttpRouter, Route


class DefaultLambdaAdapter(LambdaAdapter):
    def __init__(self, router, subject):
        # type: (HttpRouter, str) -> None
        self.subject = subject
        self.router = router

    def get_type(self, event, context):
        if self.router.get_route(Route(event["httpMethod"], event["resource"])) is None:
            raise UnhandledEventException(event)

        return LambdaEventType.sync_event

    def create_message(self, path, request):
        raise NotImplementedError()

    def create_event(self, event, context):
        body = event["body"]

        if body:
            body = body.encode('utf-8')

        api_request = ApiRequest(event["httpMethod"],
                                 event["resource"],
                                 event["pathParameters"],
                                 event["queryStringParameters"],
                                 event["headers"],
                                 body)

        return Event(self.subject, event["httpMethod"], api_request, 0, True, 0)

    def create_reply(self, path, request, message):
        if isinstance(message, SwaggerMessage):
            ret = {
                "statusCode": message.status_code
            }

            if message.body is not None:
                ret["body"] = message.body

            if message.headers is not None:
                ret["headers"] = {}
                for header in message.headers:
                    ret["headers"][header] = message.headers[header]

            return ret
        if isinstance(message.data, dict):
            ret = {
                "statusCode": message.data["statusCode"]
            }
            if "body" in message.data:
                ret["body"] = message.data["body"]

            if "headers" in message.data:
                ret["headers"] = message.data["headers"]

            return ret

        return {
            "statusCode": 500
        }
