"""OAuth2 login flow handling."""

import http.server
from collections.abc import Callable
from pathlib import Path
from typing import Any


class RedirectHandler(http.server.SimpleHTTPRequestHandler):
    """HTTPRequestHandler that handles token received on redirect uri."""

    def __init__(self, handle_authorization_response: Callable[[str], bool], *args, **kwargs):
        """Create RedirectHandler."""
        self.handle_authorization_response = handle_authorization_response
        super().__init__(*args, **kwargs)

    def do_GET(self):
        """Create response."""

        success = self.handle_authorization_response(self.path)
        filename = "auth_succesful.html" if success else "auth_failed.html"

        self.send_response(200)
        self.send_header("Content-type", "text/html")
        self.end_headers()

        with Path(__file__).with_name(filename).open("rb") as f:
            self.copyfile(f, self.wfile)

    def log_message(self, format: str, *args: Any) -> None:
        """Ignore logged messages."""


def wait_for_authorization_response(host: str, port: int) -> str:
    """Start a HTTP server and wait for a call to the callback url containing the oauth2 token."""

    class _TokenContainer:
        token: str | None = None

    container = _TokenContainer()

    def handle_code_callback(token: _TokenContainer, authorization_response):
        token.token = authorization_response

        return True

    httpd = http.server.HTTPServer(
        (host, port),
        lambda *args, **kwargs: RedirectHandler(
            lambda authorization_code: handle_code_callback(container, authorization_code),
            *args,
            **kwargs,
        ),
    )

    httpd.timeout = 300
    httpd.handle_request()

    if not container.token:
        raise TimeoutError("Did not receive a token.")

    return container.token
