# auto generated by update_py.py


from tlclient.linker.frame import Frame, FrameHeaderStatus
from tlclient.linker.constant import SubscribeTopic
from tlclient.linker.batch import MemBuffer
import tlclient.linker.frame_pb2 as frame_pb2


class Event:
    def __init__(self, s: bytes):
        pass

    def get_obj(self, MSG_TYPE):
        raise NotImplementedError

    def get_msg_type(self):
        raise NotImplementedError

    def get_nano(self):
        raise NotImplementedError

    def get_string(self) -> str:
        raise NotImplementedError

    def get_req_id(self):
        raise NotImplementedError

    def get_err_id(self):
        raise NotImplementedError

    def get_content_id(self):
        raise NotImplementedError

    def frames(self):
        raise NotImplementedError

    @staticmethod
    def new_event(msg: bytes):
        if not msg:
            return

        if msg[0] == FrameHeaderStatus.PB:
            with memoryview(msg) as m:
                return PBEvent(m[1:])
        elif msg[0] == FrameHeaderStatus.IS_BUFFER:
            return BatchFrameEvent(msg)
        elif msg[0] == FrameHeaderStatus.NORMAL:
            with memoryview(msg) as m:
                return FrameEvent(m)

    @staticmethod
    def new_pb_frame():
        return PBEvent()


class PBEvent(Event):
    def __init__(self, msg=None):
        self._index = 0
        self._mem_buffer = frame_pb2.MemBuffer()
        if msg is None:
            self._frame = self._mem_buffer.frames.add()
        else:
            self._mem_buffer.ParseFromString(msg)
            self._frame = self._mem_buffer.frames[self._index]
            self._index += 1

    def get_obj(self, MSG_TYPE):
        msg = MSG_TYPE()
        msg.ParseFromString(self._frame.data)
        return msg

    def get_msg_type(self):
        return self._frame.header.msg_type

    def get_nano(self):
        return self._frame.header.nano

    def get_string(self):
        return self._frame.data

    def get_req_id(self):
        return self._frame.header.req_id

    def get_err_id(self):
        return self._frame.header.err_id

    def get_content_id(self):
        return self._frame.header.content_id

    def frames(self):
        yield self
        while self._index < len(self._mem_buffer.frames):
            self._frame = self._mem_buffer.frames[self._index]
            self._index += 1
            yield self

    def set_status(self, status: FrameHeaderStatus):
        pass

    def set_msg_type(self, msg_type: frame_pb2.MsgType):
        self._frame.header.msg_type = msg_type

    def set_req_id(self, req_id: int):
        self._frame.header.req_id = req_id

    def set_err_id(self, err_id: int):
        self._frame.header.err_id = err_id

    def set_nano(self, nano: int):
        self._frame.header.nano = nano

    def set_source(self, source: int):
        self._frame.header.source = source

    def set_subscribe_topic(self, topic: SubscribeTopic):
        self._frame.header.content_id = SubscribeTopic.get_topic_prefix(topic)

    def set_data(self, msg):
        self._frame.data = msg.SerializeToString()

    def set_string(self, msg: str):
        self._frame.data = msg.encode()

    @property
    def buf(self):
        return (FrameHeaderStatus.PB).to_bytes(1, byteorder='little') + self._mem_buffer.SerializeToString()


class FrameEvent(Event):
    def __init__(self, msg: memoryview):
        self._frame = Frame(msg)

    def get_obj(self, MSG_TYPE):
        return self._frame.get_obj(MSG_TYPE)

    def get_msg_type(self):
        return self._frame.get_msg_type()

    def get_nano(self):
        return self._frame.get_nano()

    def get_string(self):
        return self._frame.get_string()

    def get_req_id(self):
        return self._frame.get_req_id()

    def get_err_id(self):
        return self._frame.get_err_id()

    def get_content_id(self):
        return SubscribeTopic.get_topic_prefix(self._frame.get_subscribe_topic())

    def frames(self):
        yield self


class BatchFrameEvent(Event):
    def __init__(self, msg: bytes):
        self._buffer = msg
        self._pos = MemBuffer.HEADER_LENGTH
        self._frame = Frame(self._buffer[self._pos:])

    def get_obj(self, MSG_TYPE):
        return self._frame.get_obj(MSG_TYPE)

    def get_msg_type(self):
        return self._frame.get_msg_type()

    def get_nano(self):
        return self._frame.get_nano()

    def get_string(self):
        return self._frame.get_string()

    def get_req_id(self):
        return self._frame.get_req_id()

    def get_err_id(self):
        return self._frame.get_err_id()

    def get_content_id(self):
        return SubscribeTopic.get_topic_prefix(self._frame.get_subscribe_topic())

    def frames(self):
        yield self
        while self._buffer[self._pos] == FrameHeaderStatus.HAS_NEXT:
            self._pos += self._frame.get_length()
            self._frame = Frame(self._buffer[self._pos:])
            yield self
