#!D:\IDE\Anaconda3\envs\Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
 @Author: Administrator
 @FileName: logManager.py
 @DateTime: 2025/6/21 16:52
 @SoftWare: PyCharm
 @Author  ：xsh
"""
import sys
from inspect import getframeinfo, stack
import os
import time
from PyQt5 import Qt
from AppLog.logSlot import logSlot, logSingleton
from AppLog.logUtils import logUtils, log_exception
from AppLog.logEvent import logEvent
from AppLog.logDriver import logDriver
from AppLog.LogLevel import LogLevel, LogMode
from AppLog.logInterface import logInterface
from AppInterfaces.globalSlot import globalSlot, AppSlot
from AppLog.logProcess import logProcess
class logManager(Qt.QObject, logInterface, logSingleton):
    Locker: Qt.QMutex = Qt.QMutex()

    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'logManager':
        return super(logManager, cls).GetInstance(*args, **kwargs)

    Drivers: logDriver
    Handler: dict[str, logEvent]
    Process: logProcess
    def __init__(self, parent: Qt.QObject = None):
        super(logManager, self).__init__(parent=parent)
        self.Initialization('logManager', self, parent)
        self.initConnect()
        self.Start()

    def initValue(self):
        super(logManager, self).initValue()
        self.initDrivers()
        self.initHandler()

    def deleValue(self):
        super(logManager, self).deleValue()
        self.deleHandler()

    def initConnect(self):
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.UniqueConnection | Qt.Qt.AutoConnection)
        logSlot.GetInstance().logSendSignal.connect(slot=self.log, type=TYPE)
        AppSlot.ApplicationSignal.connect(slot=self.slot_ApplicationSignal, type=Qt.Qt.ConnectionType(Qt.Qt.UniqueConnection | Qt.Qt.AutoConnection))

        pass
    #
    # def __del__(self):
    #     self.deinitialize()
    #     self.Stop()
    #     super(logManager, self).__del__()
    def slot_ApplicationSignal(self, info: object, value: object):
        try:
            self.Stop()
        except Exception as e:
            logUtils.print_Exception    (e)

    def log(self, level: int, message: str):
        src_item: logEvent = self.Handler.get(LogLevel.toString(level), None)
        # print(level, LogLevel.toString(level), LogLevel.filename(level))
        dst_item: logEvent
        if src_item is None:
            src_item = self.Handler.get(LogLevel.toString(LogLevel.LOG_DEBUG))
        dst_item = logEvent(**src_item.getEvent())
        dst_item.BUFF = message
        # print(level, LogLevel.toString(level), LogLevel.filename(level))
        # print(dst_item.TYPE, LogLevel.toString(dst_item.TYPE), LogLevel.filename(dst_item.TYPE))
        self.Drivers.Start()
        self.Drivers.push(dst_item)
        # self.initProcess()
        # self.Process.start()
        # self.Process.appendItem(dst_item)



    @property
    def hasDrivers(self) -> bool:
        return hasattr(self, 'Drivers') and isinstance(self.Drivers, logDriver  )

    @property
    def hasHandler(self) -> bool:
        return hasattr(self, 'Handler') and isinstance(self.Handler, dict       )

    def Start(self):
        self.initDrivers()
        self.Drivers.Start()



    def Stop(self):
        if self.hasDrivers:
            self.Drivers.Stop()

    def initDrivers(self):
        if not self.hasDrivers:
            self.Drivers = logDriver.GetInstance()

    def initHandler(self):
        items: list[str] = LogLevel.toList()
        item:logEvent
        if not self.hasHandler:
            self.Handler = {}
        if len(self.Handler) != len(items):
            levels: list[int] = LogLevel.all()
            for index, level in enumerate(levels):
                item = logEvent(FILE=Qt.QFile(), BUFF='', TYPE=level)
                self.Handler[items[index]] = item
                if not item.isOpen:
                    item.reopen()
        else:
            for key, item in self.Handler:
                if not item.isOpen:
                    item.reopen()
        pass

    def deleHandler(self):
        if not self.hasHandler:
            return
        item: logEvent
        for key, item in self.Handler.items():
            if item.isOpen:
                item.close()

    def initProcess(self):
        if not self.hasProcess:
            self.Process = logProcess()
    @property
    def hasProcess(self) -> bool:
        return hasattr(self, 'Process') and isinstance(self.Process, logProcess)


class LOG(Qt.QObject):
    level: int = -1
    def __init__(self, level: int = LogLevel.LOG_DEBUG, parent: Qt.QObject= None):
        super(LOG, self).__init__(parent=parent)
        self.level = level

    def __lshift__(self, *args, **kwargs):  # real signature unknown
        """ Return self<<value. """
        caller = getframeinfo(stack()[1][0])
        message = " ".join(["{}".format(i) for i in args])
        # print(os.path.split(caller.filename), caller.filename)
        string = LogLevel.Format(self.level, f"FILE:[{Qt.QFileInfo(caller.filename).baseName()}]\tLINE:[{caller.lineno}]\t{message}")
        print(string)
        logSlot.GetInstance().logSendSignal.emit(self.level, string)
        pass
