#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：WebReader.py
@Description：
@Author：XSH
@Time：2025/11/12 10:33
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5 import Qt
from AppContexts.Contexts                       import WebSocketContext
from AppInterfaces.ImplInterfaces               import WebClientInterface, WebServerInterface
from AppInterfaces.ReaderInterfaces             import WebReaderInterface
from AppInterfaces.SingletonInterface           import SingletonInterface
from AppInterfaces.AppTimeLoop                  import AppTimeLoop
from AppUtils.AppUtils                          import AppUtils
from AppCore.Requests                           import Request, Response
from AppSettings.Settings                       import (RECODE_FAILURE, RECODE_SUCCEED, SIGNAL_CONNECTION_TYPE)
from AppInterfaces.AppWebSlot                   import AppWebSlot, WebSlot

class WebReader(Qt.QObject, WebReaderInterface,SingletonInterface):
    Locker: Qt.QMutex = Qt.QMutex()
    WebServerSendSignal: Qt.pyqtSignal = Qt.pyqtSignal(object)
    WebServerReadSignal: Qt.pyqtSignal = Qt.pyqtSignal(object)
    @classmethod
    def GetInstance(cls, *args, **kwargs) -> 'WebReader':
        return super(WebReader, cls).GetInstance(*args, **kwargs)

    def __init__(self, parent: Qt.QObject = None):
        super(WebReader, self).__init__(parent=parent)
        self.Initialization('WebReader', self, parent)

    def initConnect(self):
        super(WebReader, self).initConnect()
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        self.WebServerSendSignal.connect(slot=self.slot_TransmitFrame, type=TYPE)


    def deleConnect(self):
        super(WebReader, self).deleConnect()
        try:
            self.WebServerSendSignal.disconnect(self.slot_TransmitFrame)
            if self.hasManager:
                self.Manager.deleConnect()
        except Exception as e:
            pass
    def slot_TransmitFrame(self, buffer: object):
        self.Transmit(buffer)

    def slot_ReceivedFrame(self, buffer):
        # Locker: Qt.QReadLocker = Qt.QReadLocker(self.IOLocker)
        WebSlot.WebServerReceivedSignal.emit(buffer)

    def SendRequest(self, request, **args):
        self.WebServerSendSignal.emit(request)
        AppTimeLoop.processGlobalEvents(100)


    @property
    def isAvailable(self) -> bool:
        return self.isValid and self.Manager.isAvailable

    @property
    def isValid(self) -> bool:
        return self.hasManager and self.hasParameter

    @property
    def IsOpen(self) -> bool:
        return self.isValid and self.Manager.IsOpen

    
    def Open(self, timeOut: int = 1000, **args) -> int:

        if not self.isValid:
            self.initContext()
            self.initManager()
        if not self.isValid:
            return RECODE_FAILURE
        if self.IsOpen:
            return RECODE_SUCCEED
        isWrong: int = self.Manager.Open(timeOut)
        return isWrong

    
    def Close(self, timeOut: int = 1000, **args) -> int:
        if not self.isValid:
            return RECODE_SUCCEED
        if not self.IsOpen:
            return RECODE_SUCCEED
        isWrong: int = self.Manager.Close(timeOut)
        return isWrong

    
    def initManager(self, **args):
        if not self.hasManager:
            from AppSettings.AppSetting import AppConfig
            from AppCore.AppImpls.WebServerImpl import WebServerImpl
            self.Manager = WebServerImpl(AppConfig.WebSocket.copy(), self)
            self.initServerConnect(self.Manager)

    
    def deleManager(self, **args):
        if self.hasManager:
            self.deleServerConnect(self.Manager)
            self.Manager.Close      ()
            self.Manager.deleManager()
            try:
                del self.Manager
            except Exception as e:
                AppUtils.print_Exception(e)
        self.Manager = None

    def initServerConnect(self, server):
        from AppCore.AppImpls.WebServerImpl import WebServerImpl
        if not isinstance(server, WebServerImpl):
            return
        TYPE: Qt.Qt.ConnectionType = Qt.Qt.ConnectionType(Qt.Qt.AutoConnection | Qt.Qt.UniqueConnection)
        server.ReceivedFrame.connect(slot=self.slot_ReceivedFrame, type=TYPE)

    def deleServerConnect(self, server):
        from AppCore.AppImpls.WebServerImpl import WebServerImpl
        if not isinstance(server, WebServerImpl):
            return
        try:
            server.ReceivedFrame.disconnect(self.slot_ReceivedFrame)
        except Exception as e:
            pass
        pass

    def Transmit(self, data: object, **args) -> int:
        if not self.isAvailable:
            return RECODE_FAILURE
        return self.Manager.TransmitString(buffer=data, **args)

    def Received(self, data: object, **args) -> int:
        return RECODE_FAILURE

    def Send(self, data: object, **args) -> int:
        if not self.isAvailable:
            return RECODE_FAILURE
        return self.Manager.TransmitString(buffer=data, **args)

    def Read(self, data: object, **args) -> int:
        return RECODE_FAILURE

    def WaitDone(self, buffer: object, **args) -> int:
        if not self.isAvailable:
            return RECODE_FAILURE
        return self.Manager.TransmitString(buffer=buffer, **args)

    def initContext(self):
        if not self.hasParameter:
            from AppSettings.AppSetting import AppSetting, AppConfig
            self.Parameter = AppConfig.WebSocket
        if not self.hasParameter:
            self.Parameter = WebSocketContext()

    def TransmitString(self, buffer, **args) -> int:
        if not self.isAvailable:
            return RECODE_FAILURE
        return self.Manager.TransmitString(buffer=buffer, **args)

    
    def TransmitBinary(self, buffer, **args) -> int:
        if not self.isAvailable:
            return RECODE_FAILURE
        return self.Manager.TransmitBinary(buffer=buffer, **args)

appWebReader: WebReader = WebReader.GetInstance()
AppWebSocket: WebReader = WebReader.GetInstance()