import inspect
import logging
from multiprocessing import Process, Queue

from flask import Flask
from infra.yasm.unistat import global_unistat, SuffixType

from ..settings import config_app, signal_logger
from ..utils import messages


log = logging.getLogger('werkzeug')
log.setLevel(logging.ERROR)


class Unistat(Process):
    def __init__(self,
                 unistat_queue: Queue):
        super().__init__()
        self.__unistat_queue = unistat_queue

        signal_tags = (
            ('itype', config_app['golovan.tags']['itype']),
            ('ctype', config_app['golovan.tags']['ctype']),
            ('prj', config_app['golovan.tags']['prj'])
        )

        self.__metrics = dict()
        for name, obj in inspect.getmembers(messages):
            if inspect.isclass(obj) and obj != messages.Signal and issubclass(obj, messages.Signal):
                signal = obj
                if signal.suffix_type == SuffixType.Histogram:
                    current_metric = global_unistat.create_histogram(name=signal.name,
                                                                     tags=signal_tags,
                                                                     intervals=signal.histo_intervals)
                else:
                    current_metric = global_unistat.create_float(name=signal.name,
                                                                 suffix=signal.suffix_type,
                                                                 aggregation_type=signal.aggregation_type,
                                                                 tags=signal_tags)
                self.__metrics[signal.name] = current_metric

    def run(self) -> None:
        flask_app = Flask(__name__)

        @flask_app.route(rule=config_app['golovan']['unistat_path'])
        def unistat():
            while not self.__unistat_queue.empty():
                signal: messages.Signal = self.__unistat_queue.get()
                if signal.document is not None and signal.write_to_log:
                    signal_logger.info(repr(signal))
                if signal.name in self.__metrics:
                    self.__metrics[signal.name].push(signal.get_value())

            return flask_app.response_class(response=global_unistat.to_json(),
                                            mimetype='application/json')

        flask_app.run(host=config_app['golovan']['unistat_host'],
                      port=config_app.getint('golovan', 'unistat_port'))
