from struct import Struct
from utils import bcc,FF01_TO_FF,FF_TO_FF01


class Frame(object):
    isErr = False
    errMsg = ""
    def __init__(self):
        self.stx = b'\xff\xff'
        self.rsctl = b''
        self.cmdType = b''
        self.data = b''
        self.bcc = b''
        self.etx = b'\xff'


class RsuFrame(Frame):
    def __init__(self, bit: bytes):
        super(RsuFrame, self).__init__()
        self.rsctl = b'\x30'
        self.stx = bit[0:2] #帧头前2个字节
        self.etx = bit[-1:] #帧尾最后一个字节
        content = bit[2:-1] #需要转义部分
        content = FF01_TO_FF(content.hex()) #转义操作

        try:
            self.rsctl, self.cmdType, self.data, self.bcc = Struct(
                f"!ss{len(content) - 3}ss").unpack(content)
        except Exception as e:
            self.isErr = True
            self.errMsg = f"帧解析异常:{e}"

        checkContent = f"{self.rsctl.hex()}{self.cmdType.hex()}{self.data.hex()}"
        if self.bcc.hex() != bcc(checkContent).hex():
            self.isErr = True
            self.errMsg = f"{self.data.hex()}帧不完整"



class TerFrame(Frame):
    def __init__(self,cmdType,data,fmt):
        super(TerFrame, self).__init__()
        try:
            self.cmdType = cmdType
            self._rsctl = b"\x03"
            bit = Struct(fmt).pack(*data)
        except Exception as e:
            self.isErr = True
            self.errMsg = f"发送帧解析异常:{e}"
            return

        try:
            complete = b''.join([self._rsctl,self.cmdType + bit])
            bccValue = bcc(complete.hex())
            content = FF_TO_FF01((complete+bccValue).hex())
            self.frame = (self.stx + content + self.etx)
        except Exception as e:
            self.isErr = True
            self.errMsg = f"发送帧转义异常:{e}"

    @property
    def rsctl(self):
        pass

    @rsctl.setter
    def rsctl(self, value):
        if not isinstance(value, bytes):
            raise TypeError("rsctl数据长度必须是bytes类型")
        self._rsctl = Struct("!s").pack(bytes.fromhex(value.hex()[::-1]))
