'''
{{> header}}
'''

# This file contains generated struct, enum, command definition.
# Users are not expected to import this file, instead, users can use import chip.clusters, which will import all symbols from this file and can get a readable, pretty naming like clusters.OnOff.commands.OnCommand

from dataclasses import dataclass, field
import typing
from enum import IntEnum
from chip import ChipUtility

from chip.tlv import uint, float32

from .ClusterObjects import ClusterObject, ClusterObjectDescriptor, ClusterObjectFieldDescriptor, ClusterCommand, ClusterAttributeDescriptor, Cluster, ClusterEvent
from .Types import Nullable, NullValue

{{#zcl_clusters}}
@dataclass
class {{asUpperCamelCase name}}(Cluster):
    id: typing.ClassVar[int] = {{asHex code 4}}

    @ChipUtility.classproperty
    def descriptor(cls) -> ClusterObjectDescriptor:
        return ClusterObjectDescriptor(
            Fields = [
{{#zcl_attributes_server}}
            {{#if entryType}}
                ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{asMEI manufacturerCode code}}, Type={{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}}),
            {{else}}
                ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{asMEI manufacturerCode code}}, Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}}),
            {{/if}}
{{/zcl_attributes_server}}
            ])

{{#zcl_attributes_server}}
{{#if entryType}}
    {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}}' = None
{{else}}
    {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}}' = None
{{/if}}
{{/zcl_attributes_server}}

{{#zcl_enums}}
{{#first}}
    class Enums:
{{/first}}
        class {{asType label}}(IntEnum):
{{#zcl_enum_items}}
            k{{asUpperCamelCase label}} = {{asHex value 2}}
{{/zcl_enum_items}}

{{/zcl_enums}}

{{#zcl_structs}}
{{#first}}
    class Structs:
{{/first}}
        @dataclass
        class {{asUpperCamelCase name}}(ClusterObject):
            @ChipUtility.classproperty
            def descriptor(cls) -> ClusterObjectDescriptor:
                return ClusterObjectDescriptor(
                    Fields = [
                        {{#zcl_struct_items}}
                            ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{ fieldIdentifier }}, Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}),
                        {{/zcl_struct_items}}
                    ])

            {{#zcl_struct_items}}
            {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}}
            {{/zcl_struct_items}}

{{#last}}

{{/last}}
{{/zcl_structs}}

{{#zcl_commands}}
{{#first}}
    class Commands:
{{/first}}
        @dataclass
        class {{asUpperCamelCase name}}(ClusterCommand):
            cluster_id: typing.ClassVar[int] = {{ asHex parent.code 4 }}
            command_id: typing.ClassVar[int] = {{ asHex code 4 }}
{{#if (isServer source)}}
            is_client: typing.ClassVar[bool] = False
{{else}}
            is_client: typing.ClassVar[bool] = True
{{/if}}       

            {{~#if responseName}}
            response_type: typing.ClassVar[str] = '{{asUpperCamelCase responseName}}'
            {{else}}
            response_type: typing.ClassVar[str] = None
            {{/if}}

            @ChipUtility.classproperty
            def descriptor(cls) -> ClusterObjectDescriptor:
                return ClusterObjectDescriptor(
                    Fields = [
                        {{#zcl_command_arguments}}
                            ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase label }}", Tag={{ index }}, Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}),
                        {{/zcl_command_arguments}}
                    ])

            {{#if mustUseTimedInvoke}}
            @ChipUtility.classproperty
            def must_use_timed_invoke(cls) -> bool:
                return True

            {{/if}}
            {{#zcl_command_arguments}}
            {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}}
            {{/zcl_command_arguments}}

{{/zcl_commands}}

{{#zcl_attributes_server}}
{{#first}}
    class Attributes:
{{/first}}
        @dataclass
        class {{asUpperCamelCase label}}(ClusterAttributeDescriptor):
            @ChipUtility.classproperty
            def cluster_id(cls) -> int:
                return {{ asHex parent.code 4 }}

            @ChipUtility.classproperty
            def attribute_id(cls) -> int:
                return {{ asMEI manufacturerCode code }}

            {{#if mustUseTimedWrite}}
            @ChipUtility.classproperty
            def must_use_timed_write(cls) -> bool:
                return True

            {{/if}}
            @ChipUtility.classproperty
            def attribute_type(cls) -> ClusterObjectFieldDescriptor:
            {{#if entryType}}
                return ClusterObjectFieldDescriptor(Type={{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}})
            {{else}}
                return ClusterObjectFieldDescriptor(Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}})
            {{/if}}

            {{#if entryType}}
            value: '{{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}}' = {{getPythonFieldDefault entryType ns=(asUpperCamelCase parent.name)}}
            {{else}}
            value: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.name)}}
            {{/if}}

{{/zcl_attributes_server}}

{{#zcl_events}}
{{#first}}
    class Events:
{{/first}}
        @dataclass
        class {{asUpperCamelCase name}}(ClusterEvent):
            @ChipUtility.classproperty
            def cluster_id(cls) -> int:
                return {{ asHex parent.code 4 }}

            @ChipUtility.classproperty
            def event_id(cls) -> int:
                return {{ asMEI manufacturerCode code }}

            @ChipUtility.classproperty
            def descriptor(cls) -> ClusterObjectDescriptor:
                return ClusterObjectDescriptor(
                    Fields = [
                        {{#zcl_event_fields}}
                            ClusterObjectFieldDescriptor(Label="{{ asLowerCamelCase name }}", Tag={{ fieldIdentifier }}, Type={{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}),
                        {{/zcl_event_fields}}
                    ])

            {{#zcl_event_fields}}
            {{ asLowerCamelCase name }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}}
            {{/zcl_event_fields}}

{{/zcl_events}}

{{/zcl_clusters}}
