{{> 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/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}});
        {{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}}
}
