import logging
from typing import Any, Optional

from flask import Flask, request, Response
from httpclient import HttpRequest
from httpmessagehandler import HttpMessageHandler

logger = logging.getLogger()


class FlaskMessageHandler(object):
    def __init__(self, http_message_handler):
        # type: (HttpMessageHandler) -> None
        self.http_message_handler = http_message_handler

        self.app = None

    def run(self, name, host=None, port=None):
        # type: (str, Optional[str], Optional[int]) -> Any
        self.http_message_handler.build_singletons()

        self.app = Flask(name)
        self.app.add_url_rule("/", "catch_all",
                              self.handle_messages,
                              defaults={"path": "/"},
                              methods=["GET", "POST", "PUT", "OPTIONS", "HEAD", "DELETE", "PATCH"])
        self.app.add_url_rule("/<path:path>",
                              "catch_all",
                              self.handle_messages,
                              methods=["GET", "POST", "PUT", "OPTIONS", "HEAD", "DELETE", "PATCH"])
        if host is not None:
            self.app.run(host=host, port=port)
            self.http_message_handler.destroy_singletons()

        return self.app

    def handle_messages(self, path):
        # type: (str) -> Response
        if path != "/":
            path = "/" + path

        http_request = HttpRequest(path, request.method, request.args, self._get_headers(), request.get_data())
        http_response = self.http_message_handler.handle_request(http_request)
        return Response(status=http_response.status_code,
                        response=http_response.body,
                        headers=http_response.headers)

    @staticmethod
    def _get_headers():
        headers = {}
        if request.headers is not None:
            for key in request.headers.keys():
                headers[key] = request.headers[key]
        return headers

