import logging
import logging.handlers
import pathlib
import os
import multiprocessing
import warnings

logger = logging.getLogger('insarviz')

warnings.filterwarnings('ignore', r'All-NaN (slice|axis) encountered')

def _setup_logger(log_handler):
    from PySide6.QtCore import QObject, Signal

    class LogsStoreSignals(QObject):
        new_record = Signal()
    class LogsStore(logging.Handler):
        def __init__(self):
            super().__init__()
            self._records = []
            self._signals = LogsStoreSignals()

        @property
        def records(self):
            return self._records
        @property
        def new_record(self):
            return self._signals.new_record

        def emit(self, record):
            self._records.append(record)
            self.new_record.emit()

    log_messages = LogsStore()

    queue = multiprocessing.Queue()
    queue_handler = logging.handlers.QueueHandler(queue)

    queue_listener = logging.handlers.QueueListener(queue,
                                                    log_messages,
                                                    log_handler)

    class MPFilter:
        # Filter out messages from multiprocessing.Queue, to avoid deadlocks
        # See: https://docs.python.org/3/library/logging.handlers.html#queuehandler
        def filter(self, record):
            return not (record.levelno == logging.DEBUG and record.module == 'multiprocessing')

    logger.addFilter(MPFilter())
    logger.addHandler(queue_handler)

    return log_messages, queue_listener


INSARVIZ_ROOT = str(pathlib.Path(__file__).parent.parent) + os.sep

class InsarvizFilter:
    def filter(self, record):
        return record.name.startswith("insarviz")
logger.addFilter(InsarvizFilter())
logger.setLevel(logging.DEBUG)

class InsarvizFormatter(logging.Formatter):
    def __init__(self):
        super().__init__('%(asctime)s.%(msecs)03d %(levelname)s %(modulepath)s:%(lineno)d: %(message)s',
                         datefmt = '%Y-%m-%d %H:%M:%S')
    def format(self, record):
        record.modulepath = record.pathname.removeprefix(INSARVIZ_ROOT).removesuffix(".py").replace(os.sep, ".")
        return super().format(record)

log_handler = logging.StreamHandler()
log_handler.setFormatter(InsarvizFormatter())

log_messages, log_listener = _setup_logger(log_handler)
log_listener.start()
