# Copyright (c) 2024 Analog Devices, Inc.
# SPDX-License-Identifier: Apache-2.0
"""Module defines HCI command packet codes.

This module contains the definition of the Operation
Group/Control Fields used to create opcodes for HCI
command packets.

"""
from dataclasses import dataclass
from enum import Enum
from typing import Tuple, Union


class _NopOCF(Enum):
    """
    NOP group Operation Command Fields.
    """

    NOP = 0x0


class _LinkControlOCF(Enum):
    """
    Link Control group Operation Command Fields.
    """

    INQUIRY = 0x1
    INQUIRY_CANCEL = 0x2
    PERIODIC_INQUIRY_MODE = 0x3
    EXIT_PERIODIC_INQUIRY_MODE = 0x4
    CREATE_CONNECTION = 0x5
    DISCONNECT = 0x6
    CREATE_CONNECTION_CANCEL = 0x8
    ACCEPT_CONNECTION_REQUEST = 0x9
    REJECT_CONNECTION_REQUEST = 0xA
    LINK_KEY_REQUEST_REPLY = 0xB
    LINK_KEY_REQUEST_NEGATIVE_REPLY = 0xC
    PIN_CODE_REQUEST_REPLY = 0xD
    PIN_CODE_REQUEST_NEGATIVE_REPLY = 0xE
    CHANGE_CONNECTION_PACKET_TYPE = 0xF
    AUTHENTICATION_REQUEST = 0x11
    SET_CONNECTION_ENCRYPTION = 0x13
    CHANGE_CONNECTION_LINK_KEY = 0x15
    LINK_KEY_SELECTION = 0x17
    REMOTE_NAME_REQUEST = 0x19
    REMOTE_NAME_REQUEST_CANCEL = 0x1A
    READ_REMOTE_SUPPORTED_FEATURES = 0x1B
    READ_REMOTE_EXTENDED_FEATURES = 0x1C
    READ_REMOTE_VERSION_INFORMATION = 0x1D
    READ_CLOCK_OFFSET = 0x1F
    READ_LMP_HANDLE = 0x20
    SETUP_SYNCHRONOUS_CONNECTION = 0x28
    ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST = 0x29
    REJECT_SYNCHRONOUS_CONNECTION_REQUEST = 0x2A
    IO_CAPABILITY_REQUEST_REPLY = 0x2B
    USER_CONFIRMATION_REQUEST_REPLY = 0x2C
    USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY = 0x2D
    USER_PASSKEY_REQUEST_REPLY = 0x2E
    USER_PASSKEY_REQUEST_NEGATIVE_REPLY = 0x2F
    REMOTE_OOB_DATA_REQUEST_REPLY = 0x30
    REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY = 0x33
    IO_CAPABILITY_REQUEST_NEGATIVE_REPLY = 0x34
    ENHANCED_SETUP_SYNCHRONOUS_CONNECTION = 0x3D
    ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST = 0x3E
    TRUNCATED_PAGE = 0x3F
    TRUNCATED_PAGE_CANCEL = 0x40
    SET_CONNECTIONLESS_PERIPHERAL_BROADCAST = 0x41
    SET_CONNECTIONLESS_PERIPHERAL_BROADCASE_RECEIVE = 0x42
    START_SYNCHRONIZATION_TRAIN = 0x43
    RECEIVE_SYNCHRONIZATION_TRAIN = 0x44
    REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY = 0x45


class _LinkPolicyOCF(Enum):
    """
    Link Pol;icy group Operation Command Fields.
    """

    HOLD_MODE = 0x1
    SNIFF_MODE = 0x3
    EXIT_SNIFF_MODE = 0x4
    QOS_SETUP = 0x7
    ROLE_DISCOVERY = 0x9
    SWITCH_ROLE = 0xB
    READ_LINK_POLICY_SETTINGS = 0xC
    WRITE_LINK_POLICY_SETTINGS = 0xD
    READ_DEFAULT_LINK_POLICY_SETTINGS = 0xE
    WRITE_DEFAULT_LINK_POLICY_SETTINGS = 0xF
    FLOW_SPECIFICATION = 0x10
    SNIFF_SUBRATING = 0x11


class _ControllerOCF(Enum):
    """
    Controller group Operation Command Fields.
    """

    SET_EVENT_MASK = 0x1
    RESET = 0x3
    SET_EVENT_FILTER = 0x5
    FLUSH = 0x8
    READ_PIN_TYPE = 0x9
    WRITE_PIN_TYPE = 0xA
    READ_STORED_LINK_KEY = 0xD
    WRITE_STORED_LINK_KEY = 0x11
    DELETE_STORED_LINK_KEY = 0x12
    WRITE_LOCAL_NAME = 0x13
    READ_LOCAL_NAME = 0x14
    READ_CONNECTION_ACCEPT_TIMEOUT = 0x15
    WRITE_CONNECTION_ACCEPT_TIMEOUT = 0x16
    READ_PAGE_TIMEOUT = 0x17
    WRITE_PAGE_TIMEOUT = 0x18
    READ_SCAN_ENABLE = 0x19
    WRITE_SCAN_ENABLE = 0x1A
    READ_PAGE_SCAN_ACTIVITY = 0x1B
    WRITE_PAGE_SCAN_ACTIVITY = 0x1C
    READ_INQUIRY_SCAN_ACTIVITY = 0x1D
    WRITE_INQUIRY_SCAN_ACTIVITY = 0x1E
    READ_AUTHENTICATION_ENABLE = 0x1F
    WRITE_AUTHENTICATION_ENABLE = 0x20
    READ_CLASS_OF_DEVICE = 0x23
    WRITE_CLASS_OF_DEVICE = 0x24
    READ_VOICE_SETTING = 0x25
    WRITE_VOICE_SETTING = 0x26
    READ_AUTOMATIC_FLUSH_TIMEOUT = 0x27
    WRITE_AUTOMATIC_FLUSH_TIMEOUT = 0x28
    READ_NUM_BROADCAST_RETRANSMISSIONS = 0x29
    WRITE_NUM_BROADCAST_RETRANSMISSIONS = 0x2A
    READ_HOLD_MODE_ACTIVITY = 0x2B
    WRITE_HOLD_MODE_ACTIVITY = 0x2C
    READ_TRANSMIT_POWER_LEVEL = 0x2D
    READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x2E
    WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE = 0x2F
    SET_CONTROLLER_TO_HOST_FLOW_CONTROL = 0x31
    HOST_BUFFER_SIZE = 0x33
    HOST_NUMBER_OF_COMPLETED_PACKETS = 0x35
    READ_LINK_SUPERVISION_TIMEOUT = 0x36
    WRITE_LINK_SUPERVISION_TIMEOUT = 0x37
    READ_NUMBER_OF_SUPPORTED_IAC = 0x38
    READ_CURRENT_IAC_LAP = 0x39
    WRITE_CURRENT_IAC_LAP = 0x3A
    SET_AFH_HOST_CHANNEL_CLASSIFICATION = 0x3F
    READ_INQUIRY_SCAN_TYPE = 0x42
    WRITE_INQUIRY_SCAN_TYPE = 0x43
    READ_INQUIRY_MODE = 0x44
    WRITE_INQUIRY_MODE = 0x45
    READ_PAGE_SCAN_TYPE = 0x46
    WRITE_PAGE_SCAN_TYPE = 0x47
    READ_AFH_CHANNEL_ASSESSMENT_MODE = 0x48
    WRITE_AFH_CHANNEL_ASSESSMENT_MODE = 0x49
    READ_EXTENDED_INQUIRY_RESPONSE = 0x51
    WRITE_EXTENDED_INQUIRY_RESPONSE = 0x52
    REFRESH_ENCRYPTION_KEY = 0x53
    READ_SIMPLE_PAIRING_MODE = 0x55
    WRITE_SIMPLE_PAIRING_MODE = 0x56
    READ_LOCAL_OOB_DATA = 0x57
    READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL = 0x58
    WRITE_INQUIRY_TRANSMIT_POWER_LEVEL = 0x59
    READ_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x5A
    WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING = 0x5B
    ENHANCED_FLUSH = 0x5F
    SEND_KEYPRESS_NOTIFICATION = 0x60
    SET_EVENT_MASK_PAGE_2 = 0x63
    READ_FLOW_CONTROL_MODE = 0x66
    WRITE_FLOW_CONTROL_MODE = 0x67
    READ_ENHANCED_TRANSMIT_POWER_LEVEL = 0x68
    READ_LE_HOST_SUPPORT = 0x6C
    WRITE_LE_HOST_SUPPORT = 0x6D
    SET_MWS_CHANNEL_PARAMETERS = 0x6E
    SET_EXTERNAL_FRAME_CONFIGURATION = 0x6F
    SET_MWS_SIGNALING = 0x70
    SET_MWS_TRANSPORT_LAYER = 0x71
    SET_MWS_SCAN_FREQUENCY_TABLE = 0x72
    SET_MWS_PATTERN_CONFIGURATION = 0x73
    SET_RESERVED_LT_ADDR = 0x74
    DELETE_RESERVED_LT_ADDR = 0x75
    SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA = 0x76
    READ_SYNCHRONIZATION_TRAIN_PARAMETERS = 0x77
    WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS = 0x78
    READ_SECURE_CONNECTIONS_HOST_SUPPORT = 0x79
    WRITE_SECURE_CONNECTIONS_HOST_SUPPORT = 0x7A
    READ_AUTHENTICATED_PAYLOAD_TIMEOUT = 0x7B
    WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT = 0x7C
    READ_LOCAL_OOB_EXTENDED_DATA = 0x7D
    READ_EXTENDED_PAGE_TIMEOUT = 0x7E
    WRITE_EXTENDED_PAGE_TIMEOUT = 0x7F
    READ_EXTENDED_INQUIRY_LENGTH = 0x80
    WRITE_EXTENDED_INQUIRY_LENGTH = 0x81
    SET_ECOSYSTEM_BASE_INTERVAL = 0x82
    CONFIGURE_DATA_PATH = 0x83
    SET_MIN_ENCRYPTION_KEY_SIZE = 0x84


class _InformationalOCF(Enum):
    """
    Informational group Operation Command Fields.
    """

    READ_LOCAL_VERSION_INFORMATION = 0x1
    READ_LOCAL_SUPPORTED_COMMANDS = 0x2
    READ_LOCAL_SUPPORTED_FEATURES = 0x3
    READ_LOCAL_EXTENDED_FEATURES = 0x4
    READ_BUFFER_SIZE = 0x5
    READ_BD_ADDR = 0x9
    READ_DATA_BLOCK_SIZE = 0xA
    READ_LOCAL_SUPPORTED_CODECS_V1 = 0xB
    READ_LOCAL_SIMPLE_PAIRING_OPTIONS = 0xC
    READ_LOCAL_SUPPORTED_CODECS_V2 = 0xD
    READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES = 0xE
    READ_LOCAL_SUPPORTED_CONTROLLER_DELAY = 0xF


class _StatusOCF(Enum):
    """
    Status group Operation Command Fields.
    """

    READ_FAILED_CONTACT_COUNTER = 0x1
    RESET_FAILED_CONTACT_COUNTER = 0x2
    READ_LINK_QUALITY = 0x3
    READ_RSSI = 0x5
    READ_AFH_CHANNEL_MAP = 0x6
    READ_CLOCK = 0x7
    READ_ENCRYPTION_KEY_SIZE = 0x8
    GET_MWS_TRANSPORT_LAYER_CONFIGURATION = 0xC
    SET_TRIGGERED_CLOCK_CAPTURE = 0xD


class _TestingOCF(Enum):
    """
    Testing group Operation Command Fields.
    """

    READ_LOOPBACK_MODE = 0x1
    WRITE_LOOPBACK_MODE = 0x2
    ENABLE_DEVICE_UNDER_TEST_MODE = 0x3
    WRITE_SIMPLE_PAIRING_DEBUG_MODE = 0x4
    WRITE_SECURE_CONNECTIONS_TEST_MODE = 0xA


class _LEControllerOCF(Enum):
    """
    LE Controller group Operation Command Fields.
    """

    LE_SET_EVENT_MASK = 0x1
    LE_READ_BUFFER_SIZE_V1 = 0x2
    LE_READ_LOCAL_SUPPORTED_FEATURES = 0x3
    LE_SET_RANDOM_ADDRESS = 0x5
    LE_SET_ADVERTISING_PARAMETERS = 0x6
    LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 0x7
    LE_SET_ADVERTISING_DATA = 0x8
    LE_SET_SCAN_RESPONSE_DATA = 0x9
    LE_SET_ADVERTISING_ENABLE = 0xA
    LE_SET_SCAN_PARAMETERS = 0xB
    LE_SET_SCAN_ENABLE = 0xC
    LE_CREATE_CONNECTION = 0xD
    LE_CREATE_CONNECTION_CANCEL = 0xE
    LE_READ_FILTER_ACCEPT_LIST_SIZE = 0xF
    LE_CLEAR_FILTER_ACCEPT_LIST = 0x10
    LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST = 0x11
    LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST = 0x12
    LE_CONNECTION_UPDATE = 0x13
    LE_SET_HOST_CHANNEL_CLASSIFICATION = 0x14
    LE_READ_CHANNEL_MAP = 0x15
    LE_READ_REMOTE_FEATURES = 0x16
    LE_ENCRYPT = 0x17
    LE_RAND = 0x18
    LE_ENABLE_ENCRYPTION = 0x19
    LE_LONG_TERM_KEY_REQUEST_REPLY = 0x1A
    LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY = 0x1B
    LE_READ_SUPPORTED_STATES = 0x1C
    LE_RECEIVER_TEST_V1 = 0x1D
    LE_TRANSMITTER_TEST_V1 = 0x1E
    LE_TEST_END = 0x1F
    LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY = 0x20
    LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY = 0x21
    LE_SET_DATA_LENGTH = 0x22
    LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH = 0x23
    LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH = 0x24
    LE_READ_LOCAL_P256_PUBLIC_KEY = 0x25
    LE_GENERATE_DHKEY_V1 = 0x26
    LE_ADD_DEVICE_TO_RESOLVING_LIST = 0x27
    LE_REMOVE_DEVICE_FROM_RESOLVING_LIST = 0x28
    LE_CLEAR_RESOLVING_LIST = 0x29
    LE_READ_RESOLVING_LIST_SIZE = 0x2A
    LE_READ_PEER_RESOLVABLE_ADDRESS = 0x2B
    LE_READ_LOCAL_RESOLVABLE_ADDRESS = 0x2C
    LE_SET_ADDRESS_RESOLUTION_ENABLE = 0x2D
    LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT = 0x2E
    LE_READ_MAXIMUM_DATA_LENGTH = 0x2F
    LE_READ_PHY = 0x30
    LE_SET_DEFAULT_PHY = 0x31
    LE_SET_PHY = 0x32
    LE_RECEIVER_TEST_V2 = 0x33
    LE_TRANSMITTER_TEST_V2 = 0x34
    LE_SET_ADVERTISING_SET_RANDOM_ADDRESS = 0x35
    LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V1 = 0x36
    LE_SET_EXTENDED_ADVERTISING_DATA = 0x37
    LE_SET_EXTENDED_SCAN_RESPONSE_DATA = 0x38
    LE_SET_EXTENDED_ADVERTISING_ENABLE = 0x39
    LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH = 0x3A
    LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS = 0x3B
    LE_REMOVE_ADVERTISING_SET = 0x3C
    LE_CLEAR_ADVERTISING_SETS = 0x3D
    LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V1 = 0x3E
    LE_SET_PERIODIC_ADVERTISING_DATA = 0x3F
    LE_SET_PERIODIC_ADVERTISING_ENABLE = 0x40
    LE_SET_EXTENDED_SCAN_PARAMETERS = 0x41
    LE_SET_EXTENDED_SCAN_ENABLE = 0x42
    LE_EXTENDED_CREATE_CONNECTION_V1 = 0x43
    LE_PERIODIC_ADVERTISING_CREATE_SYNC = 0x44
    LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL = 0x45
    LE_PERIODIC_ADVERTISING_TERMINATE_SYNC = 0x46
    LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST = 0x47
    LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST = 0x48
    LE_CLEAR_PERIODIC_ADVERTISER_LIST = 0x49
    LE_READ_PERIODIC_ADVERTISER_LIST_SIZE = 0x4A
    LE_READ_TRANSMIT_POWER = 0x4B
    LE_READ_RF_PATH_COMPENSATION = 0x4C
    LE_WRITE_RF_PATH_COMPENSATION = 0x4D
    LE_SET_PRIVACY_MODE = 0x4E
    LE_RECEIVER_TEST_V3 = 0x4F
    LE_TRANSMITTER_TEST_V3 = 0x50
    LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS = 0x51
    LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE = 0x52
    LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE = 0x53
    LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS = 0x54
    LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS = 0x55
    LE_CONNECTION_CTE_REQUEST_ENABLE = 0x56
    LE_CONNECTION_CTE_RESPONSE_ENABLE = 0x57
    LE_READ_ANTENNA_INFORMATION = 0x58
    LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE = 0x59
    LE_PERIODIC_ADVERTISING_SYNC_TRANSFER = 0x5A
    LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER = 0x5B
    LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 0x5C
    LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS = 0x5D
    LE_GENERATE_DHKEY_V2 = 0x5E
    LE_MODIFY_SLEEP_CLOCK_ACCURACY = 0x5F
    LE_READ_BUFFER_SIZE_V2 = 0x60
    LE_READ_ISO_TX_SYNC = 0x61
    LE_SET_CIG_PARAMETERS = 0x62
    LE_SET_CIG_PARAMETERS_TEST = 0x63
    LE_CREATE_CIS = 0x64
    LE_REMOVE_CIG = 0x65
    LE_ACCEPT_CIS_REQUEST = 0x66
    LE_REJECT_CIS_REQUEST = 0x67
    LE_CREATE_BIG = 0x68
    LE_CREATE_BIG_TEST = 0x69
    LE_TERMINATE_BIG = 0x6A
    LE_BIG_CREATE_SYNC = 0x6B
    LE_BIG_TERMINATE_SYNC = 0x6C
    LE_REQUEST_PEER_SCA = 0x6D
    LE_SETUP_ISO_DATA_PATH = 0x6E
    LE_REMOVE_ISO_DATA_PATH = 0x6F
    LE_ISO_TRANSMIT_TEST = 0x70
    LE_ISO_RECEIVE_TEST = 0x71
    LE_ISO_READ_TEST_COUNTERS = 0x72
    LE_ISO_TEST_END = 0x73
    LE_SET_HOST_FEATURE_V1 = 0x74
    LE_READ_ISO_LINK_QUALITY = 0x75
    LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL = 0x76
    LE_READ_REMOTE_TRANSMIT_POWER_LEVEL = 0x77
    LE_SET_PATH_LOSS_REPORTING_PARAMETERS = 0x78
    LE_SET_PATH_LOSS_REPORTING_ENABLE = 0x79
    LE_SET_TRANSMIT_POWER_REPORTING_ENABLE = 0x7A
    LE_TRANSMITTER_TEST_V4 = 0x7B
    LE_SET_DATA_RELATED_ADDRESS_CHANGES = 0x7C
    LE_SET_DEFAULT_SUBRATE = 0x7D
    LE_SUBRATE_REQUEST = 0x7E
    LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2 = 0x7F
    LE_SET_DECISION_DATA = 0x80
    LE_SET_DECISION_INSTRUCTIONS = 0x81
    LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA = 0x82
    LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA = 0x83
    LE_SET_PERIODIC_SYNC_SUBEVENT = 0x84
    LE_EXTENDED_CREATE_CONNECTION_V2 = 0x85
    LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2 = 0x86
    LE_READ_ALL_LOCAL_SUPPORTED_FEATURES = 0x87
    LE_READ_ALL_REMOTE_FEATURES = 0x88
    LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES = 0x89
    LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES = 0x8A
    LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES = 0x8B
    LE_CS_SECURITY_ENABLE = 0x8C
    LE_CS_SET_DEFAULT_SETTINGS = 0x8D
    LE_CS_READ_REMOTE_FAE_TABLE = 0x8E
    LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE = 0x8F
    LE_CS_CREATE_CONFIG = 0x90
    LE_CS_REMOVE_CONFIG = 0x91
    LE_CS_SET_CHANNEL_CLASSIFICATION = 0x92
    LE_CS_SET_PROCEDURE_PARAMETERS = 0x93
    LE_CS_PROCEDURE_ENABLE = 0x94
    LE_CS_TEST = 0x95
    LE_CS_TEST_END = 0x96
    LE_SET_HOST_FEATURE_V2 = 0x97
    LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST = 0x98
    LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST = 0x99
    LE_CLEAR_MONITORED_ADVERTISERS_LIST = 0x9A
    LE_READ_MONITORED_ADVERTISERS_LIST_SIZE = 0x9B
    LE_ENABLE_MONITORING_ADVERTISERS = 0x9C
    LE_FRAME_SPACE_UPDATE = 0x9D


class OGF(Enum):
    """
    Command packet Operation Group Fields.
    """

    NOP = 0x00
    LINK_CONTROL = 0x01
    LINK_POLICY = 0x02
    CONTROLLER = 0x03
    INFORMATIONAL = 0x04
    STATUS = 0x05
    TESTING = 0x06
    LE_CONTROLLER = 0x08
    VENDOR_SPECIFIC = 0x3F


@dataclass(frozen=True, init=False)
class OCF:
    """Command packet Operation Command Fields.

    Attributes
    ----------
    NOP : Enum
        NOP group OCFs.
    LINK_CONTROL : Enum
        Link Control group OCFs.
    LINK_POLICY : Enum
        Link Policy group OCFs.
    CONTROLLER : Enum
        Controller group OCFs.
    INFORMATIONAL : Enum
        Informational group OCFs.
    STATUS : Enum
        Status group OCFs.
    TESTING : Enum
        Testing group OCFs.
    LE_CONTROLLER : Enum
        LE Controller group OCFs.

    """

    NOP = _NopOCF
    LINK_CONTROL = _LinkControlOCF
    LINK_POLICY = _LinkPolicyOCF
    CONTROLLER = _ControllerOCF
    INFORMATIONAL = _InformationalOCF
    STATUS = _StatusOCF
    TESTING = _TestingOCF
    LE_CONTROLLER = _LEControllerOCF


def parse_opcode(opcode: int) -> Tuple[OGF, Union[OCF, int]]:
    """Extract Operation Group/Command Fields from an HCI command opcode.

    Parameters
    ----------
    opcode : int
        HCI command opcode to parse.

    Returns
    -------
    OGF
        HCI command Operation Group Field.
    Union[OCF, int]
        HCI command Operation Command Field. If the HCI
        command is vendor-specific, this value is an integer.

    """
    ogf = OGF(opcode >> 10)
    ocf = opcode & 0xFF

    if ogf == OGF.NOP:
        ocf = OCF.NOP.NOP
    elif ogf == OGF.LINK_CONTROL:
        ocf = OCF.LINK_CONTROL(ocf)
    elif ogf == OGF.CONTROLLER:
        ocf = OCF.CONTROLLER(ocf)
    elif ogf == OGF.INFORMATIONAL:
        ocf = OCF.INFORMATIONAL(ocf)
    elif ogf == OGF.STATUS:
        ocf = OCF.STATUS(ocf)
    elif ogf == OGF.LE_CONTROLLER:
        ocf = OCF.LE_CONTROLLER(ocf)
    return ogf, ocf
