#!/usr/bin/env python
'''
@file hci_event_factory.py

@brief HCI event factory

Copyright (C) Atmosic 2025
'''
from __future__ import annotations
from logging import getLogger

from packet.base.packet_factory_base import PacketFactoryBase
from packet.hci.hci_packet_implement import HciEvent, HciBootStatusEvent, \
    HciEventVendorSpecific, HciEventCommandComplete, HciProgInfoRsp, \
    HciProgBlkClean, HciProgBaudrateSet, HciProgWriteData, HciProgApplyBlk, \
    HciProgXorCheck, HciProgSha256Check, HciProgDump, HciDiagnoTput, \
    HciDiagnoLatency

logger = getLogger(__name__)

class HciEventFactory(PacketFactoryBase):
    def create_packet(self, data: bytes) -> HciEvent:
        """Create packet from raw bytes.
        
        Args:
            data: Raw packet bytes (already detected/sliced by detector)
            
        Returns:
            HciEvent: Created HCI event instance
        """
        hci_event = HciEvent.from_bytes(data)
        logger.debug(f"create {hci_event}")
        if hci_event.evtcode == 0x0E:
            hci_event_cc = HciEventCommandComplete.from_bytes(data)
            logger.debug(f"the evtcode is 0x0E, create {hci_event_cc}")
            if hci_event_cc.opcode == 0xF870:
                evt = HciProgInfoRsp.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF871:
                evt = HciProgBlkClean.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF872:
                evt = HciProgBaudrateSet.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF873:
                evt = HciProgWriteData.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF874:
                evt = HciProgApplyBlk.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF875:
                evt = HciProgXorCheck.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF876:
                evt = HciProgSha256Check.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF877:
                evt = HciProgDump.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF880:
                evt = HciDiagnoTput.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            elif hci_event_cc.opcode == 0xF881:
                evt = HciDiagnoLatency.EventCC.from_bytes(data)
                logger.debug(f"the opcode is {hci_event_cc.opcode:04X},"
                             f" create {evt}")
                return evt
            return hci_event_cc
        elif hci_event.evtcode == 0xFF:
            evt_vs = HciEventVendorSpecific.from_bytes(data)
            logger.debug(f"the evtcode is 0xFF, create {evt_vs}")
            if evt_vs.sub_event == 0x70:
                evt = HciBootStatusEvent.EventVS.from_bytes(data)
                logger.debug(f"the subevte is 0x70, create {evt}")
                return evt
            return evt_vs
        return hci_event
