#!D:/IDE/anaconda3/envs/Microscope_Scan python
# -*- coding: UTF-8 -*-
"""
@FileName：ModBusImplInterface.py
@Description：
@Author：XSH
@Time：2025/11/11 12:52
@Department：研发部
@Copyright：©2025 乐辰生物
"""
import clr
import socket
import gc
import struct
from clr_loader.types                           import Assembly, ClrFunction    #
from PyQt5                                      import Qt                       #
from abc                                        import abstractmethod           #
from AppInterfaces.ImplInterface                import ImplInterface
from AppContexts.Contexts                       import ModBusContext, ModBusRegister
from AppSettings.Settings                       import (RECODE_FAILURE, RECODE_SUCCEED)


class ModBusImplInterface(ImplInterface):
    Manager: 'YQLModBus'  #
    Controller: 'YQLMController'  #
    Parameter: ModBusContext  #
    Number: int

    @property
    @abstractmethod
    def isAvailable(self) -> bool:
        return self.hasManager and self.IsOpen

    @property
    def hasController(self) -> bool:
        return hasattr(self, 'Controller') and self.Controller is not None

    @property
    def controller(self) -> 'YQLMController':
        return self.Controller if self.hasController else None

    @property
    def parameter(self) -> ModBusContext:
        return self.Parameter if self.hasParameter else None

    @property
    def hasManager(self) -> bool:
        return hasattr(self, 'Manager') and self.Manager is not None

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

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

    @property
    def hasSocket(self) -> bool:
        return self.hasManager and hasattr(self.Manager, 'socket') and self.Manager.socket is not None

    @property
    def socket(self) -> socket.socket:
        if self.hasSocket:
            return self.Manager.socket
        return None

    @property
    def isclosed(self) -> bool:
        return not self.hasManager or not self.Manager.IsAvailable

    @property
    def is_socket_connected(self) -> bool:
        return self.hasManager and self.Manager.IsAvailable

    @abstractmethod
    def IsOpen(self) -> bool:
        raise Exception('Interface Instance error')

    @abstractmethod
    def isEnabled(self) -> bool:
        raise Exception('Interface Instance error')

    @abstractmethod
    def isDisable(self) -> bool:
        raise Exception('Interface Instance error')

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

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

    @abstractmethod
    def initManager(self, context: object, **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 ReConnected(self):
        raise Exception('Interface Instance error')

    def ReOpen(self, timeOut: int = 1000) -> int:
        self.Close(timeOut)
        return self.Open(timeOut)

    @property
    def hasNumber(self) -> bool:
        return self.has_field("Number", int)

    @property
    def number(self) -> int:
        return 0 if not self.hasNumber else self.Number

    @property
    def ReConnectedNumber(self) -> int:
        return self.parameter.ReConnected

    def initNumber(self):
        if not self.hasNumber:
            self.Number = 0

    @abstractmethod
    def ReadRegister(self, address: int):
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadRegisters(self, address: int, Count: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadCoil(self, address: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadCoils(self, address: int, Count: int, values: list[bool]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendCoil(self, address: int, value: bool) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendCoils(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendRegister(self, address: int, value: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadFloats(self, address: int, Count: int, values: list[float]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadFloat(self, address: int) -> float:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendFloats(self, address: int, values: list[float]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendFloat(self, address: int, value: float) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadInt32(self, address: int):
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadInt32s(self, address: int, Count: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendInt32(self, address: int, value: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendInt32s(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadUInt32(self, address: int):
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadUInt32s(self, address: int, Count: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendUInt32(self, address: int, value: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendUInt32s(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadInt16(self, address: int):
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadInt16s(self, address: int, Count: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendInt16(self, address: int, value: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendInt16s(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadUInt16(self, address: int):
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadUInt16s(self, address: int, Count: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendUInt16(self, address: int, value: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendUInt16s(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadState(self, address: int) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def ReadStatus(self, address: int, Count: int, values: list[bool]) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendState(self, address: int, value: bool) -> int:
        raise Exception('Interface Instance error')

    @abstractmethod
    def SendStatus(self, address: int, values: list[int]) -> int:
        raise Exception('Interface Instance error')

