# Path: beacontools/structs/ibeacon.py

# 
# Path: beacontools/structs/eddystone.py

# 
# Path: beacontools/structs/estimote.py

# 
# Path: beacontools/structs/controlj.py

# 
# Path: beacontools/structs/exposure_notification.py

# 
# Path: beacontools/const.py
# SERVICE_DATA_TYPE = 0x16
# 
# MANUFACTURER_SPECIFIC_DATA_TYPE = 0xFF
# 
# EDDYSTONE_UUID = b"\xaa\xfe"
# 
# ESTIMOTE_UUID = b"\x9a\xfe"
# 
# EDDYSTONE_UID_FRAME = 0x00
# 
# EDDYSTONE_URL_FRAME = 0x10
# 
# EDDYSTONE_TLM_FRAME = 0x20
# 
# EDDYSTONE_EID_FRAME = 0x30
# 
# ESTIMOTE_TELEMETRY_FRAME = 0x2
# 
# ESTIMOTE_MANUFACTURER_ID = b"\x5d\x01"
# 
# CJ_MANUFACTURER_ID = b"\x72\x04"
# 
# FLAGS_DATA_TYPE = 0x01
# 
# IBEACON_MANUFACTURER_ID = b"\x4c\x00"
# 
# EXPOSURE_NOTIFICATION_UUID = b"\x6f\xfd"


from construct import Struct, Byte, Switch, OneOf, Array, Bytes, GreedyRange, BitStruct, \
                      BitsInteger, Flag
from .ibeacon import IBeaconMSD
from .eddystone import EddystoneUIDFrame, EddystoneURLFrame, EddystoneTLMFrame, EddystoneEIDFrame
from .estimote import EstimoteTelemetryFrame, EstimoteNearableFrame
from .controlj import CJMonitorMSD
from .exposure_notification import ExposureNotificationFrame
from ..const import SERVICE_DATA_TYPE, MANUFACTURER_SPECIFIC_DATA_TYPE, EDDYSTONE_UUID, \
                    ESTIMOTE_UUID, EDDYSTONE_UID_FRAME, EDDYSTONE_URL_FRAME, EDDYSTONE_TLM_FRAME, \
                    EDDYSTONE_EID_FRAME, ESTIMOTE_TELEMETRY_FRAME, ESTIMOTE_MANUFACTURER_ID, \
                    CJ_MANUFACTURER_ID, FLAGS_DATA_TYPE, IBEACON_MANUFACTURER_ID, \
                    EXPOSURE_NOTIFICATION_UUID
            "frame" / Switch(lambda ctx: ctx.frame_type, {
                EDDYSTONE_UID_FRAME: EddystoneUIDFrame,
                EDDYSTONE_URL_FRAME: EddystoneURLFrame,
                EDDYSTONE_TLM_FRAME: EddystoneTLMFrame,
                EDDYSTONE_EID_FRAME: EddystoneEIDFrame,
            })
        ),
        ESTIMOTE_UUID:  Struct(
            "frame_type" / Byte,
            "frame" / Switch(lambda ctx: ctx.frame_type & 0xF, {
                ESTIMOTE_TELEMETRY_FRAME: EstimoteTelemetryFrame,
            })
        ),
    })
)

ManufacturerSpecificData = Struct(
    "company_identifier" / Bytes(2),
    "data" / Switch(lambda ctx: ctx.company_identifier, {
        ESTIMOTE_MANUFACTURER_ID: EstimoteNearableFrame,
        CJ_MANUFACTURER_ID: CJMonitorMSD,
        IBEACON_MANUFACTURER_ID: IBeaconMSD,
    })
)

LTV = Struct(
    "length" / Byte,
    "type" / Byte,
    "value" / Switch(lambda ctx: ctx.type, {
        FLAGS_DATA_TYPE: AdvertisingFlags,

# Path: beacontools/structs/ibeacon.py

# 
# Path: beacontools/structs/eddystone.py

# 
# Path: beacontools/structs/estimote.py

# 
# Path: beacontools/structs/controlj.py

# 
# Path: beacontools/structs/exposure_notification.py

# 
# Path: beacontools/const.py
# SERVICE_DATA_TYPE = 0x16
# 
# MANUFACTURER_SPECIFIC_DATA_TYPE = 0xFF
# 
# EDDYSTONE_UUID = b"\xaa\xfe"
# 
# ESTIMOTE_UUID = b"\x9a\xfe"
# 
# EDDYSTONE_UID_FRAME = 0x00
# 
# EDDYSTONE_URL_FRAME = 0x10
# 
# EDDYSTONE_TLM_FRAME = 0x20
# 
# EDDYSTONE_EID_FRAME = 0x30
# 
# ESTIMOTE_TELEMETRY_FRAME = 0x2
# 
# ESTIMOTE_MANUFACTURER_ID = b"\x5d\x01"
# 
# CJ_MANUFACTURER_ID = b"\x72\x04"
# 
# FLAGS_DATA_TYPE = 0x01
# 
# IBEACON_MANUFACTURER_ID = b"\x4c\x00"
# 
# EXPOSURE_NOTIFICATION_UUID = b"\x6f\xfd"


# Path: beacontools/structs/common.py
from construct import Struct, Byte, Switch, OneOf, Array, Bytes, GreedyRange, BitStruct, \
                      BitsInteger, Flag
from .ibeacon import IBeaconMSD
from .eddystone import EddystoneUIDFrame, EddystoneURLFrame, EddystoneTLMFrame, EddystoneEIDFrame
from .estimote import EstimoteTelemetryFrame, EstimoteNearableFrame
from .controlj import CJMonitorMSD
from .exposure_notification import ExposureNotificationFrame
from ..const import SERVICE_DATA_TYPE, MANUFACTURER_SPECIFIC_DATA_TYPE, EDDYSTONE_UUID, \
                    ESTIMOTE_UUID, EDDYSTONE_UID_FRAME, EDDYSTONE_URL_FRAME, EDDYSTONE_TLM_FRAME, \
                    EDDYSTONE_EID_FRAME, ESTIMOTE_TELEMETRY_FRAME, ESTIMOTE_MANUFACTURER_ID, \
                    CJ_MANUFACTURER_ID, FLAGS_DATA_TYPE, IBEACON_MANUFACTURER_ID, \
                    EXPOSURE_NOTIFICATION_UUID

            "frame" / Switch(lambda ctx: ctx.frame_type, {
                EDDYSTONE_UID_FRAME: EddystoneUIDFrame,
                EDDYSTONE_URL_FRAME: EddystoneURLFrame,
                EDDYSTONE_TLM_FRAME: EddystoneTLMFrame,
                EDDYSTONE_EID_FRAME: EddystoneEIDFrame,
            })
        ),
        ESTIMOTE_UUID:  Struct(
            "frame_type" / Byte,
            "frame" / Switch(lambda ctx: ctx.frame_type & 0xF, {
                ESTIMOTE_TELEMETRY_FRAME: EstimoteTelemetryFrame,
            })
        ),
    })
)

ManufacturerSpecificData = Struct(
    "company_identifier" / Bytes(2),
    "data" / Switch(lambda ctx: ctx.company_identifier, {
        ESTIMOTE_MANUFACTURER_ID: EstimoteNearableFrame,
        CJ_MANUFACTURER_ID: CJMonitorMSD,
        IBEACON_MANUFACTURER_ID: IBeaconMSD,
    })
)

LTV = Struct(
    "length" / Byte,
    "type" / Byte,
    "value" / Switch(lambda ctx: ctx.type, {
        FLAGS_DATA_TYPE: AdvertisingFlags,

        SERVICE_DATA_TYPE: ServiceData,