from zigpy import types as t
from zigpy.zcl import Cluster, foundation

NET_START = (
    t.uint32_t,
    t.EUI64,
    t.uint8_t,
    t.KeyData,
    t.uint8_t,
    t.NWK,
    t.NWK,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.EUI64,
    t.NWK,
)

NET_JOIN = (
    t.uint32_t,
    t.EUI64,
    t.uint8_t,
    t.KeyData,
    t.uint8_t,
    t.uint8_t,
    t.NWK,
    t.NWK,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
    t.uint16_t,
)


class DeviceInfoRecord(t.Struct):
    _fields = [
        ("ieee", t.EUI64),
        ("endpoint_id", t.uint8_t),
        ("profile_id", t.uint16_t),
        ("device_id", t.uint16_t),
        ("version", t.uint8_t),
        ("group_id_count", t.uint8_t),
        ("sort", t.uint8_t),
    ]


class EndpointInfoRecord(t.Struct):
    _fields = [
        ("nwk", t.NWK),
        ("endpoint_id", t.uint8_t),
        ("profile_id", t.uint16_t),
        ("device_id", t.uint16_t),
        ("version", t.uint8_t),
    ]


class GroupInfoRecord(t.Struct):
    _fields = [("group_id", t.Group), ("group_type", t.uint8_t)]


class LightLink(Cluster):
    cluster_id = 0x1000
    ep_attribute = "lightlink"
    attributes = {}
    server_commands = {
        0x0000: ("scan", (t.uint32_t, t.bitmap8, t.bitmap8), False),
        0x0002: ("device_information", (t.uint32_t, t.uint8_t), False),
        0x0006: ("identify", (t.uint32_t, t.uint16_t), False),
        0x0007: ("reset_to_factory_new", (t.uint32_t,), False),
        0x0010: ("network_start", NET_START, False),
        0x0012: ("network_join_router", NET_JOIN, False),
        0x0014: ("network_join_end_device", NET_JOIN, False),
        0x0016: (
            "network_update",
            (t.uint32_t, t.EUI64, t.uint8_t, t.uint8_t, t.NWK, t.NWK),
            False,
        ),
        0x0041: ("get_group_identifiers", (t.uint8_t,), False),
        0x0042: ("get_endpoint_list", (t.uint8_t,), False),
    }
    client_commands = {
        0x0001: (
            "scan_rsp",
            (
                t.uint32_t,
                t.uint8_t,
                t.bitmap8,
                t.bitmap8,
                t.bitmap16,
                t.uint32_t,
                t.EUI64,
                t.uint8_t,
                t.uint8_t,
                t.NWK,
                t.NWK,
                t.uint8_t,
                t.uint8_t,
                t.Optional(t.uint8_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint16_t),
                t.Optional(t.uint8_t),
                t.Optional(t.uint8_t),
            ),
            True,
        ),
        0x0003: (
            "device_information_rsp",
            (t.uint32_t, t.uint8_t, t.uint8_t, t.LVList(DeviceInfoRecord)),
            True,
        ),
        0x0011: (
            "network_start_rsp",
            (t.uint32_t, foundation.Status, t.EUI64, t.uint8_t, t.uint8_t, t.uint16_t),
            True,
        ),
        0x0013: ("network_join_router_rsp", (t.uint32_t, foundation.Status), True),
        0x0015: ("network_join_end_device_rsp", (t.uint32_t, foundation.Status), True),
        0x0040: (
            "endpoint_information",
            (t.EUI64, t.NWK, t.uint8_t, t.uint16_t, t.uint16_t, t.uint8_t),
            True,
        ),
        0x0041: (
            "get_group_identifiers_rsp",
            (t.uint8_t, t.uint8_t, t.LVList(GroupInfoRecord)),
            True,
        ),
        0x0042: (
            "get_endpoint_list_rsp",
            (t.uint8_t, t.uint8_t, t.LVList(EndpointInfoRecord)),
            True,
        ),
    }
