{{> header}}

#pragma once

#include <cstdint>
#include <string>
#include <type_traits>

#include <app-common/zap-generated/cluster-objects.h>
#include <commands/clusters/ComplexArgument.h>
#include <commands/clusters/ClusterCommand.h>
#include <commands/clusters/ReportCommand.h>
#include <commands/clusters/WriteAttributeCommand.h>

{{> clusters_header}}

{{#chip_client_clusters}}
{{> cluster_header}}

{{#chip_cluster_commands}}
/*
 * Command {{asUpperCamelCase name}}
 */
class {{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}: public ClusterCommand
{
public:
    {{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}(): ClusterCommand("{{asDelimitedCommand name}}"){{#chip_cluster_command_arguments}}{{#if isComplex}}, mComplex_{{asUpperCamelCase label}}(&mRequest.{{asLowerCamelCase label}}){{/if}}{{/chip_cluster_command_arguments}}
    {
        {{#chip_cluster_command_arguments}}
        {{~#*inline "field"}}mRequest.{{asLowerCamelCase label}}{{/inline~}}
        {{#if isComplex}}
        AddArgument("{{asUpperCamelCase label}}", &mComplex_{{asUpperCamelCase label}});
        {{else if (isString type)}}
        AddArgument("{{asUpperCamelCase label}}", &{{>field}});
        {{else}}
        AddArgument("{{asUpperCamelCase label}}", {{asTypeMinValue type}}, {{asTypeMaxValue type}}, &{{>field}});
        {{/if}}
        {{/chip_cluster_command_arguments}}
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(ChipDevice * device, chip::EndpointId endpointId) override
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) command ({{asHex code 8}}) on endpoint %" PRIu16, endpointId);

        return ClusterCommand::SendCommand(device, endpointId, {{asHex parent.code 8}}, {{asHex code 8}}, mRequest);
    }

private:
    chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Type mRequest;
    {{#chip_cluster_command_arguments}}
    {{#if isComplex}}
    TypedComplexArgument<{{zapTypeToEncodableClusterObjectType type ns=parent.parent.name}}> mComplex_{{asUpperCamelCase label}};
    {{/if}}
    {{/chip_cluster_command_arguments}}
};

{{/chip_cluster_commands}}

{{#chip_server_cluster_attributes}}
{{! TODO: Various types (floats, structs) not supported here. }}
{{#unless (isStrEqual chipCallback.name "Unsupported")}}
{{#if isWritableAttribute}}
class Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public WriteAttribute
{
public:
    Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): WriteAttribute("{{asUpperCamelCase name}}"){{#if isComplex}}, mComplex(&mValue){{/if}}
    {
        AddArgument("attr-name", "{{asDelimitedCommand (asUpperCamelCase name)}}");
        {{#if isComplex}}
        AddArgument("attr-value", &mComplex);
        {{else if (isString type)}}
        AddArgument("attr-value", &mValue);
        {{else}}
        AddArgument("attr-value", {{asTypeMinValue type}}, {{asTypeMaxValue type}}, &mValue);
        {{/if}}
        WriteAttribute::AddArguments();
    }

    ~Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}() {}

    CHIP_ERROR SendCommand(ChipDevice * device, chip::EndpointId endpointId) override
    {
        return WriteAttribute::SendCommand(device, endpointId, {{asHex parent.code 8}}, {{asHex code 8}}, mValue);
    }

private:
    {{zapTypeToEncodableClusterObjectType type ns=parent.name}} mValue;
{{#if isComplex}}
    TypedComplexArgument<{{zapTypeToEncodableClusterObjectType type ns=parent.name}}> mComplex;
{{/if}}
};

{{/if}}
{{/unless}}
{{/chip_server_cluster_attributes}}
{{/chip_client_clusters}}

/*----------------------------------------------------------------------------*\
| Register all Clusters commands                                               |
\*----------------------------------------------------------------------------*/
{{#chip_client_clusters}}
void registerCluster{{asUpperCamelCase name}}(Commands & commands)
{
    using namespace chip::app::Clusters::{{asUpperCamelCase name}};

    const char * clusterName = "{{asUpperCamelCase name}}";

    commands_list clusterCommands = {
        //
        // Commands
        //
        make_unique<ClusterCommand>(Id), //
        {{#chip_cluster_commands}}
        make_unique<{{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}>(), //
        {{/chip_cluster_commands}}
        //
        // Attributes
        //
        make_unique<ReadAttribute>(Id), //
        {{#chip_server_cluster_attributes}}
        make_unique<ReadAttribute>(Id, "{{asDelimitedCommand (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id), //
        {{/chip_server_cluster_attributes}}
        make_unique<WriteAttribute>(Id), //
        {{#chip_server_cluster_attributes}}
        {{! TODO: Various types (floats, structs) not supported here. }}
        {{#unless (isStrEqual chipCallback.name "Unsupported")}}
        {{#if isWritableAttribute}}
        make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/unless}}
        {{/chip_server_cluster_attributes}}
        make_unique<SubscribeAttribute>(Id), //
        {{#chip_server_cluster_attributes}}
        {{#if isReportableAttribute}}
        make_unique<SubscribeAttribute>(Id, "{{asDelimitedCommand (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id), //
        {{/if}}
        {{/chip_server_cluster_attributes}}
        //
        // Events
        //
        make_unique<ReadEvent>(Id), //
        {{#chip_server_cluster_events}}
        make_unique<ReadEvent>(Id, "{{asDelimitedCommand (asUpperCamelCase name)}}", Events::{{asUpperCamelCase name}}::Id), //
        {{/chip_server_cluster_events}}
        make_unique<SubscribeEvent>(Id), //
        {{#chip_server_cluster_events}}
        make_unique<SubscribeEvent>(Id, "{{asDelimitedCommand (asUpperCamelCase name)}}", Events::{{asUpperCamelCase name}}::Id), //
        {{/chip_server_cluster_events}}
    };

    commands.Register(clusterName, clusterCommands);
}
{{/chip_client_clusters}}

void registerClusterAny(Commands & commands)
{
    const char * clusterName = "Any";

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(),  //
        make_unique<ReadAttribute>(),   //
        make_unique<WriteAttribute>(),  //
        make_unique<SubscribeAttribute>(), //
        make_unique<ReadEvent>(),       //
        make_unique<SubscribeEvent>(),     //
    };

    commands.Register(clusterName, clusterCommands);
}

void registerClusters(Commands & commands)
{
    registerClusterAny(commands);
{{#chip_client_clusters}}
    registerCluster{{asUpperCamelCase name}}(commands);
{{/chip_client_clusters}}
}
