import logging
import typing as t

from prometheus_client import REGISTRY, CollectorRegistry
from prometheus_client.exposition import _bake_output
from prometheus_client.exposition import parse_qs, urlparse

from app.classes.web.base_api_handler import BaseApiHandler

logger = logging.getLogger(__name__)


class BaseMetricsHandler(BaseApiHandler):
    """HTTP handler that gives metrics from ``REGISTRY``."""

    registry: CollectorRegistry = REGISTRY
    # registry.unregister(GC_COLLECTOR)
    # registry.unregister(PLATFORM_COLLECTOR)
    # registry.unregister(PROCESS_COLLECTOR)

    def get_registry(self) -> None:
        # Prepare parameters
        registry = self.registry
        accept_header = self.request.headers.get("Accept")
        accept_encoding_header = self.request.headers.get("Accept-Encoding")
        params = parse_qs(urlparse(self.request.path).query)
        # Bake output
        status, headers, output = _bake_output(
            registry, accept_header, accept_encoding_header, params, False
        )
        # Return output
        self.finish_metrics(int(status.split(" ", maxsplit=1)[0]), headers, output)

    @classmethod
    def factory(cls, registry: CollectorRegistry) -> type:
        """Returns a dynamic MetricsHandler class tied
        to the passed registry.
        """
        # This implementation relies on MetricsHandler.registry
        #  (defined above and defaulted to REGISTRY).

        # As we have unicode_literals, we need to create a str()
        #  object for type().
        cls_name = str(cls.__name__)
        MyMetricsHandler = type(cls_name, (cls, object), {"registry": registry})
        return MyMetricsHandler

    def finish_metrics(self, status: int, headers, data: t.Dict[str, t.Any]):
        self.set_status(status)
        self.set_header("Content-Type", "text/plain")
        for header in headers:
            self.set_header(*header)
        self.finish(data)