#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：WebClientInterface.py
@Description：
@Author：XSH
@Time：2025/11/11 12:53
@Department：研发部
@Copyright：©2025 乐辰生物
"""
from PyQt5 import Qt
from abc import abstractmethod
from AppInterfaces.ImplInterface import ImplInterface
from AppContexts.Contexts import WebSocketContext
from AppInterfaces.AppTimeLoop import AppTimeLoop
from AppUtils.AppConvert import AppConvert
from AppSettings.Settings import RECODE_SUCCEED, RECODE_FAILURE
SOCKET_DEFAULT_DELAY        : int = 50
SOCKET_MAX_CONNECT_DELAY    : int = 2000
class WebClientInterface(ImplInterface):
    Manager     : Qt.QWebSocket
    Parameter   : WebSocketContext
    @property
    def manager     (self) -> Qt.QWebSocket     :
        return self.Manager     if self.hasManager   else None
    @property
    def parameter   (self) -> WebSocketContext  :
        return self.Parameter   if self.hasParameter else None
    def setParameter(self, value):
        self.Parameter = value if isinstance(value, WebSocketContext) else None

    @property
    def hasManager(self) -> bool:
        return hasattr(self, 'Manager') and isinstance(self.Manager, Qt.QWebSocket)

    @property
    def hasParameter(self) -> bool:
        return hasattr(self, 'Parameter') and isinstance(self.Parameter, WebSocketContext)

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

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

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

    @property
    def isDisable(self) -> bool:
        return not self.IsOpen

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

    def ReOpen(self, **args) -> int:
        self.Close(**args)
        return self.Open(**args)

    @abstractmethod
    def Open(self, timeOut: int = 1000, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def Close(self, timeOut: int = 1000, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def initManager(self, **args):
        raise Exception('Interface Instance error')

    @abstractmethod
    def deleManager(self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def initContext(self):
        raise Exception('Interface Instance error')

    @abstractmethod
    def TransmitString(self, buffer, **args) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def TransmitBinary(self, buffer, **args) -> int:
        raise Exception('Interface Instance error')

    def __eq__(self, other):
        return isinstance(other, self.__class__) and self.manager.peerAddress().toString().lower() == other.manager.peerAddress().toString().lower() and self.manager.peerPort() == other.manager.peerPort()

    @staticmethod
    def SocketSendString(socket: Qt.QWebSocket, buffer: str) -> int:
        global SOCKET_DEFAULT_DELAY, SOCKET_MAX_CONNECT_DELAY
        isWrong: int = RECODE_FAILURE
        if not isinstance(socket, Qt.QWebSocket) or AppConvert.isEmpty(buffer):
            return isWrong
        try:
            OtherLength: int = socket.bytesToWrite()
            MaxLength: int = len(buffer)
            SendLength: int
            while OtherLength > 0:
                AppTimeLoop.processGlobalEvents(SOCKET_DEFAULT_DELAY)
                OtherLength = socket.bytesToWrite()
            SendLength = socket.sendTextMessage(buffer)
            OtherLength = socket.bytesToWrite()
            while OtherLength > 0:
                AppTimeLoop.processGlobalEvents(SOCKET_DEFAULT_DELAY)
                OtherLength = socket.bytesToWrite()
            isWrong = SendLength == MaxLength or OtherLength <= 0
        except Exception as e:
            from AppLog.logHelper import logWEBSERVER
            logWEBSERVER << AppUtils.toString(e)
        return isWrong

    @staticmethod
    def SocketSendBinary(socket: Qt.QWebSocket, buffer: bytes) -> int:
        global  SOCKET_DEFAULT_DELAY ,SOCKET_MAX_CONNECT_DELAY
        isWrong: int = RECODE_FAILURE
        if not isinstance(socket, Qt.QWebSocket) or not isinstance(buffer, bytes) or len(buffer) <= 0:
            return isWrong
        try:
            # OtherLength: int = socket.bytesToWrite()
            # while OtherLength > 0:
            #     AppTimeLoop.processGlobalEvents(SOCKET_DEFAULT_DELAY)
            #     OtherLength = socket.bytesToWrite()
            MaxLength: int = len(buffer)
            # SendLength: int
            SendLength = socket.sendBinaryMessage(buffer)
            # OtherLength = socket.bytesToWrite()
            # while OtherLength > 0:
            #     AppTimeLoop.processGlobalEvents(SOCKET_DEFAULT_DELAY)
            #     OtherLength = socket.bytesToWrite()
            isWrong = SendLength == MaxLength

        except Exception as e:
            from AppLog.logHelper import logWEBSERVER
            logWEBSERVER << AppUtils.toString(e)
        return isWrong

    @staticmethod
    def SocketClose(socket: Qt.QWebSocket, Parameter: WebSocketContext) -> int:
        isWrong: int = RECODE_SUCCEED
        if not isinstance(socket, Qt.QWebSocket) or not isinstance(Parameter, WebSocketContext):
            return isWrong
        try:
            socket.close()
            Parameter.IsOpen = False
        except Exception as e:
            from AppLog.logHelper import logWEBSERVER
            logWEBSERVER << AppUtils.toString(e)
        return isWrong

    @staticmethod
    def SocketOpen(socket: Qt.QWebSocket, Parameter: WebSocketContext) -> int:
        isWrong: int = RECODE_FAILURE
        if not isinstance(socket, Qt.QWebSocket) or not isinstance(Parameter, WebSocketContext):
            return isWrong
        WebClientInterface.SocketClose(socket, Parameter)
        Parameter.IsOpen = False
        try:
            socket.open(Qt.QUrl(Parameter.API))
            isWrong = RECODE_SUCCEED

        except Exception as e:
            from AppLog.logHelper import logWEBSERVER
            logWEBSERVER << AppUtils.toString(e)
            isWrong = RECODE_FAILURE
        return isWrong
    @staticmethod
    def EqualSocket(Manager: Qt.QWebSocket, Parameter: WebSocketContext) -> bool:
        if not isinstance(Manager, Qt.QWebSocket) or not isinstance(Parameter, WebSocketContext):
            return False
        return Manager.requestUrl().toString().lower() == Qt.QUrl(Parameter.API).toString().lower()