from tornado.web import RequestHandler

GLOBAL_CHARSET = "utf-8"


class AsgiHandler(RequestHandler):
    def initialize(self, asgi_app) -> None:
        super().initialize()
        self._asgi_app = asgi_app

    async def handle_request(self):
        headers = []
        for k in self.request.headers:
            for v in self.request.headers.get_list(k):
                headers.append((k.encode(GLOBAL_CHARSET).lower(), v.encode(GLOBAL_CHARSET)))

        scope = {
            "type": self.request.protocol,
            "http_version": self.request.version,
            "path": self.request.path,
            "method": self.request.method,
            "query_string": self.request.query.encode(GLOBAL_CHARSET),
            "headers": headers,
            "client": (self.request.remote_ip, 0),
        }

        async def receive():
            return {"body": self.request.body, "type": "http.request", "more_body": False}

        async def send(data):
            if data["type"] == "http.response.start":
                self.set_status(data["status"])
                self.clear_header("content-type")
                self.clear_header("server")
                self.clear_header("date")
                for h in data["headers"]:
                    if len(h) == 2:
                        self.add_header(h[0].decode(GLOBAL_CHARSET), h[1].decode(GLOBAL_CHARSET))
            elif data["type"] == "http.response.body":
                self.write(data["body"])
            else:
                raise RuntimeError(f"Unsupported response type \"{data['type']}\" for asgi app")

        await self._asgi_app(scope, receive, send)

    async def get(self):
        await self.handle_request()

    async def post(self):
        await self.handle_request()
