{{> header}}

#pragma once

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

#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>
#include <commands/common/Commands.h>
#include <commands/clusters/ComplexArgument.h>
#include <commands/clusters/ClusterCommand.h>
#include <commands/clusters/ReportCommand.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}}{{#if isOptional}}, "", Argument::kOptional{{/if}});
        {{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
    {
        constexpr chip::ClusterId clusterId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Id;
        constexpr chip::CommandId commandId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Id;

        ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointIds.at(0));
        return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest);
    }

    CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override
    {
        constexpr chip::ClusterId clusterId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Id;
        constexpr chip::CommandId commandId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Id;

        ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, groupId);

        return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, 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_chip_complex}}
        make_unique<WriteAttributeAsComplex<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}>>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, WriteCommandType::k{{#unless isWritable}}Force{{/unless}}Write, 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, WriteCommandType::k{{#unless isWritable}}Force{{/unless}}Write, 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, WriteCommandType::k{{#unless isWritable}}Force{{/unless}}Write, credsIssuerConfig), //
        {{/if_chip_complex}}
        {{/zcl_attributes_server}}
        make_unique<SubscribeAttribute>(Id, credsIssuerConfig), //
        {{#zcl_attributes_server}}
        make_unique<SubscribeAttribute>(Id, "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}", Attributes::{{asUpperCamelCase name}}::Id, credsIssuerConfig), //
        {{/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.RegisterCluster(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<ReadNone>(credsIssuerConfig),         //
        make_unique<ReadAll>(credsIssuerConfig),         //
        make_unique<SubscribeNone>(credsIssuerConfig),         //
        make_unique<SubscribeAll>(credsIssuerConfig),         //
    };

    commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for sending IM messages based on cluster id, not cluster name.");
}

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