{{> 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/SubscriptionsCommands.h>
#include <commands/clusters/WriteAttributeCommand.h>

{{> clusters_header}}

{{#zcl_clusters}}
{{> cluster_header}}

{{#zcl_commands_source_client}}
/*
 * Command {{asUpperCamelCase name}}
 */
class {{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ClusterCommand
{
public:
    {{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(CredentialIssuerCommands * credsIssuerConfig): ClusterCommand("{{cleanse_label_as_kebab_case name}}", credsIssuerConfig){{#zcl_command_arguments}}{{#if_chip_complex}}, mComplex_{{asUpperCamelCase label}}(&mRequest.{{asLowerCamelCase label}}){{/if_chip_complex}}{{/zcl_command_arguments}}
    {
        {{#zcl_command_arguments}}
        {{#if_chip_complex}}
        AddArgument("{{asUpperCamelCase label}}", &mComplex_{{asUpperCamelCase label}});
        {{else if (isString type)}}
        AddArgument("{{asUpperCamelCase label}}", &mRequest.{{asLowerCamelCase label}});
        {{else}}
        AddArgument("{{asUpperCamelCase label}}", {{as_type_min_value type language='c++'}}, {{as_type_max_value type language='c++'}}, &mRequest.{{asLowerCamelCase label}});
        {{/if_chip_complex}}
        {{/zcl_command_arguments}}
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector<chip::EndpointId> endpointIds) override
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) command ({{asHex code 8}}) on endpoint %u", endpointIds.at(0));

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

    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) command ({{asHex code 8}}) on Group %u", groupId);

        return ClusterCommand::SendGroupCommand(groupId, fabricIndex, {{asHex parent.code 8}}, {{asHex code 8}}, mRequest);
    }

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

{{/zcl_commands_source_client}}

{{/zcl_clusters}}

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

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

    commands_list clusterCommands = {
        //
        // Commands
        //
        make_unique<ClusterCommand>(Id, credsIssuerConfig), //
        {{#zcl_commands_source_client}}
        make_unique<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(credsIssuerConfig), //
        {{/zcl_commands_source_client}}
        //
        // Attributes
        //
        make_unique<ReadAttribute>(Id, credsIssuerConfig), //
        {{#zcl_attributes_server}}
        make_unique<ReadAttribute>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/zcl_attributes_server}}
        make_unique<WriteAttribute<>>(Id, credsIssuerConfig), //
        {{#zcl_attributes_server}}
        {{#if isWritable}}
        {{#if_chip_complex}}
        make_unique<WriteAttributeAsComplex<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}>>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{else if (isString type)}}
        make_unique<WriteAttribute<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}>>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{else}}
        make_unique<WriteAttribute<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}>>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", {{as_type_min_value type language='c++'}}, {{as_type_max_value type language='c++'}}, Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/if_chip_complex}}
        {{/if}}
        {{/zcl_attributes_server}}
        make_unique<SubscribeAttribute>(Id, credsIssuerConfig), //
        {{#zcl_attributes_server}}
        {{#if isReportable}}
        make_unique<SubscribeAttribute>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/if}}
        {{/zcl_attributes_server}}
        //
        // Events
        //
        make_unique<ReadEvent>(Id, credsIssuerConfig), //
        {{#zcl_events}}
        make_unique<ReadEvent>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Events::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/zcl_events}}
        make_unique<SubscribeEvent>(Id, credsIssuerConfig), //
        {{#zcl_events}}
        make_unique<SubscribeEvent>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Events::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/zcl_events}}
    };

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

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

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

    commands.Register(clusterName, clusterCommands);
}

void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssuerConfig)
{
    registerClusterAny(commands, credsIssuerConfig);
{{#zcl_clusters}}
    registerCluster{{asUpperCamelCase name}}(commands, credsIssuerConfig);
{{/zcl_clusters}}
    registerClusterSubscriptions(commands, credsIssuerConfig);
}
