{{> header}}

#pragma once

#import <Matter/Matter.h>

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

#include <commands/clusters/ComplexArgument.h>
#include <app/data-model/DecodableList.h>
#include <commands/clusters/ClusterCommandBridge.h>
#include <commands/clusters/ReportCommandBridge.h>
#include <commands/clusters/WriteAttributeCommandBridge.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app-common/zap-generated/ids/Clusters.h>
#include <app-common/zap-generated/ids/Commands.h>

{{> clusters_header}}

{{#zcl_clusters}}
{{#if (isSupported (asUpperCamelCase name preserveAcronyms=true))}}
{{#if (isProvisional (asUpperCamelCase name preserveAcronyms=true))}}
#if MTR_ENABLE_PROVISIONAL
{{/if}}
{{> cluster_header}}

{{#zcl_commands}}
{{#if (is_str_equal source 'client')}}
{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
{{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
#if MTR_ENABLE_PROVISIONAL
{{/if}}
/*
 * Command {{asUpperCamelCase name}}
 */
class {{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ClusterCommand
{
public:
    {{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): ClusterCommand("{{cleanse_label_as_kebab_case name}}"){{#zcl_command_arguments}}{{#if_chip_complex}}, mComplex_{{asUpperCamelCase label}}(&mRequest.{{asLowerCamelCase label}}){{/if_chip_complex}}{{/zcl_command_arguments}}
    {
        {{#zcl_command_arguments}}
        {{#if (isProvisional (asUpperCamelCase parent.parent.name preserveAcronyms=true) command=(asUpperCamelCase parent.name preserveAcronyms=true) commandField=(asStructPropertyName label))}}
        #if MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{#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}}
        {{#if (isProvisional (asUpperCamelCase parent.parent.name preserveAcronyms=true) command=(asUpperCamelCase parent.name preserveAcronyms=true) commandField=(asStructPropertyName label))}}
        #endif // MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{/zcl_command_arguments}}
        ClusterCommand::AddArguments();
    }

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) 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, endpointId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name preserveAcronyms=true}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}}Params alloc] init];
        params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        {{#zcl_command_arguments}}
        {{#if (isProvisional (asUpperCamelCase parent.parent.name preserveAcronyms=true) command=(asUpperCamelCase parent.name preserveAcronyms=true) commandField=(asStructPropertyName label))}}
        #if MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{>decodable_value target=(concat "params." (asStructPropertyName label)) source=(concat "mRequest." (asLowerCamelCase label)) cluster=parent.parent.name type=type depth=0}}
        {{#if (isProvisional (asUpperCamelCase parent.parent.name preserveAcronyms=true) command=(asUpperCamelCase parent.name preserveAcronyms=true) commandField=(asStructPropertyName label))}}
        #endif // MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{/zcl_command_arguments}}
        uint16_t repeatCount = mRepeatCount.ValueOr(1);
        uint16_t __block responsesNeeded = repeatCount;
        while (repeatCount--)
        {
            [cluster {{asLowerCamelCase name}}WithParams:params completion:
            {{#if hasSpecificResponse}}
                ^(MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase responseName}}Params * _Nullable values, NSError * _Nullable error) {
                    NSLog(@"Values: %@", values);
                    if (error == nil) {
                        constexpr chip::CommandId responseId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase responseName}}::Id;
                        RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values);
                    }
            {{else}}
                ^(NSError * _Nullable error) {
            {{/if}}
                    responsesNeeded--;
                    if (error != nil) {
                        mError = error;
                        LogNSError("Error", error);
                        {{#if hasSpecificResponse}}
                          constexpr chip::CommandId responseId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase responseName}}::Id;
                          RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error);
                        {{else}}
                          RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error);
                        {{/if}}
                    }
                    if (responsesNeeded == 0) {
                        SetCommandExitStatus(mError);
                    }
                }];
        }
        return CHIP_NO_ERROR;
    }

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

{{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
#endif // MTR_ENABLE_PROVISIONAL
{{/if}}
{{/if}}
{{/if}}
{{/zcl_commands}}

{{#zcl_attributes_server removeKeys='isOptional'}}
{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
{{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
#if MTR_ENABLE_PROVISIONAL
{{/if}}
{{#*inline "cluster"}}Cluster{{asUpperCamelCase parent.name preserveAcronyms=true}}{{/inline}}
{{#*inline "attribute"}}Attribute{{asUpperCamelCase name preserveAcronyms=true}}{{/inline}}

/*
 * Attribute {{asUpperCamelCase name}}
 */
class Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public ReadAttribute
{
public:
    Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): ReadAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}")
    {
    }

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

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        constexpr chip::ClusterId clusterId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Id;
        constexpr chip::AttributeId attributeId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::Id;

        ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId);

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBase{{>cluster}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        {{#if_is_fabric_scoped_struct type}}
        __auto_type * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
          params.filterByFabric = mFabricFiltered.Value();
        }
        {{/if_is_fabric_scoped_struct}}
        [cluster read{{>attribute}}With
        {{~#if_is_fabric_scoped_struct type~}}
        Params:params completion:
        {{~else~}}
        Completion:
        {{~/if_is_fabric_scoped_struct~}}
        ^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
        NSLog(@"{{asUpperCamelCase parent.name preserveAcronyms=true}}.{{asUpperCamelCase name preserveAcronyms=true}} response %@", [value description]);
        if (error == nil) {
          RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value);
        } else {
          LogNSError("{{asUpperCamelCase parent.name preserveAcronyms=true}} {{asUpperCamelCase name preserveAcronyms=true}} read Error", error);
          RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error);
        }
        SetCommandExitStatus(error);
         }];
        return CHIP_NO_ERROR;
    }

};

{{#if isWritableAttribute}}
{{! No list support for writing yet.  Need to figure out how to represent the
    values. }}
class Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public WriteAttribute
{
public:
    Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): WriteAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}"){{#if_chip_complex}}, mComplex(&mValue){{/if_chip_complex}}
    {
        AddArgument("attr-name", "{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}");
        {{#if_chip_complex}}
        AddArgument("attr-value", &mComplex);
        {{else if (isString type)}}
        AddArgument("attr-value", &mValue);
        {{else}}
        AddArgument("attr-value", {{as_type_min_value type language='c++'}}, {{as_type_max_value type language='c++'}}, &mValue);
        {{/if_chip_complex}}
        WriteAttribute::AddArguments();
    }

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

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        constexpr chip::ClusterId clusterId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Id;
        constexpr chip::AttributeId attributeId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::Id;

        ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBase{{>cluster}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRWriteParams alloc] init];
        params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil;
        {{#if_chip_complex}}
        {{asObjectiveCType type parent.name}} value;
        {{>decodable_value target="value" source="mValue" cluster=parent.name errorCode="return err;" depth=0}}
        {{else}}
          {{#if isNullable}}
            {{asObjectiveCType type parent.name}} value = nil;
            if (!mValue.IsNull()) {
              {{#if (isOctetString type)}}
                value = [[NSData alloc] initWithBytes:mValue.Value().data() length:mValue.Value().size()];
              {{else if (isString type)}}
                value = [[NSString alloc] initWithBytes:mValue.Value().data() length:mValue.Value().size() encoding:NSUTF8StringEncoding];
              {{else}}
                value = [NSNumber numberWith{{asObjectiveCNumberType "" type false}}:mValue.Value()];
              {{/if}}
            }
          {{else}}
            {{#if (isOctetString type)}}
              {{asObjectiveCType type parent.name}} value = [[NSData alloc] initWithBytes:mValue.data() length:mValue.size()];
            {{else if (isString type)}}
              {{asObjectiveCType type parent.name}} value = [[NSString alloc] initWithBytes:mValue.data() length:mValue.size() encoding:NSUTF8StringEncoding];
            {{else}}
              {{asObjectiveCType type parent.name}} value = [NSNumber numberWith{{asObjectiveCNumberType "" type false}}:mValue{{#if isNullable}}.Value(){{/if}}];
            {{/if}}
          {{/if}}
        {{/if_chip_complex}}

        [cluster write{{>attribute}}WithValue:value params:params completion:^(NSError * _Nullable error) {
            if (error != nil) {
              LogNSError("{{asUpperCamelCase parent.name preserveAcronyms=true}} {{asUpperCamelCase name preserveAcronyms=true}} write Error", error);
              RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error);
            }
            SetCommandExitStatus(error);
            }];
        return CHIP_NO_ERROR;
    }

private:
    {{#if_chip_complex}}
    {{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}} mValue;
    TypedComplexArgument<{{zapTypeToEncodableClusterObjectType type ns=parent.name forceNotOptional=true}}> mComplex;
    {{else if (isOctetString type)}}
    {{#if isNullable}}chip::app::DataModel::Nullable<chip::ByteSpan>{{else}}chip::ByteSpan{{/if}} mValue;
    {{else if (isCharString type)}}
    {{#if isNullable}}chip::app::DataModel::Nullable<chip::ByteSpan>{{else}}chip::ByteSpan{{/if}} mValue;
    {{else}}
    {{#if isNullable}}chip::app::DataModel::Nullable<{{as_underlying_zcl_type type}}>{{else}}{{as_underlying_zcl_type type}}{{/if}} mValue;
    {{/if_chip_complex}}
};

{{/if}}
{{#if isReportableAttribute}}
class SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}: public SubscribeAttribute
{
public:
    SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}(): SubscribeAttribute("{{cleanse_label_as_kebab_case (asUpperCamelCase name)}}")
    {
    }

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

    CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override
    {
        constexpr chip::ClusterId clusterId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Id;
        constexpr chip::CommandId attributeId = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::Id;

        ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId);
        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBase{{>cluster}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)];
        if (mKeepSubscriptions.HasValue()) {
          params.replaceExistingSubscriptions = !mKeepSubscriptions.Value();
        }
        if (mFabricFiltered.HasValue()) {
          params.filterByFabric = mFabricFiltered.Value();
        }
        if (mAutoResubscribe.HasValue()) {
          params.resubscribeAutomatically = mAutoResubscribe.Value();
        }
        [cluster subscribe{{>attribute}}WithParams:params
                                subscriptionEstablished:^(){ mSubscriptionEstablished=YES; }
                                reportHandler:^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
        NSLog(@"{{asUpperCamelCase parent.name preserveAcronyms=true}}.{{asUpperCamelCase name preserveAcronyms=true}} response %@", [value description]);
            if (error == nil) {
              RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value);
            } else {
              RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error);
            }
        SetCommandExitStatus(error);
         }];

        return CHIP_NO_ERROR;
    }
};

{{/if}}
{{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
#endif // MTR_ENABLE_PROVISIONAL
{{/if}}
{{/if}}
{{/zcl_attributes_server}}
{{#if (isProvisional (asUpperCamelCase name preserveAcronyms=true))}}
#endif // MTR_ENABLE_PROVISIONAL
{{/if}}
{{/if}}
{{/zcl_clusters}}

/*----------------------------------------------------------------------------*\
| Register all Clusters commands                                               |
\*----------------------------------------------------------------------------*/
{{#zcl_clusters}}
{{#if (isSupported (asUpperCamelCase name preserveAcronyms=true))}}
void registerCluster{{asUpperCamelCase name}}(Commands & commands)
{
{{#if (isProvisional (asUpperCamelCase name preserveAcronyms=true))}}
#if MTR_ENABLE_PROVISIONAL
{{/if}}
    using namespace chip::app::Clusters::{{asUpperCamelCase name}};

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

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        {{#zcl_commands}}
        {{#if (is_str_equal source 'client')}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
        #if MTR_ENABLE_PROVISIONAL
        {{/if}}
        make_unique<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
        #endif // MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{/if}}
        {{/if}}
        {{/zcl_commands}}
        {{#zcl_attributes_server removeKeys='isOptional'}}
        {{#first}}
         make_unique<ReadAttribute>(Id), //
         make_unique<WriteAttribute>(Id), //
         make_unique<SubscribeAttribute>(Id), //
        {{/first}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        #if MTR_ENABLE_PROVISIONAL
        {{/if}}
        make_unique<Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{#if isWritableAttribute}}
        make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{#if isReportableAttribute}}
        make_unique<SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{#if (isProvisional (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        #endif // MTR_ENABLE_PROVISIONAL
        {{/if}}
        {{/if}}
        {{/zcl_attributes_server}}
        {{#zcl_events}}
        {{#first}}
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
        {{/first}}
        {{/zcl_events}}
    };

    commands.RegisterCluster(clusterName, clusterCommands);
{{#if (isProvisional (asUpperCamelCase name preserveAcronyms=true))}}
#endif // MTR_ENABLE_PROVISIONAL
{{/if}}
}
{{/if}}
{{/zcl_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>(chip::kInvalidClusterId, true), //
        make_unique<SubscribeEvent>(),     //
    };

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

void registerClusters(Commands & commands)
{
    registerClusterAny(commands);
{{#zcl_clusters}}
    {{#if (isSupported (asUpperCamelCase name preserveAcronyms=true))}}
    registerCluster{{asUpperCamelCase name}}(commands);
    {{/if}}
{{/zcl_clusters}}
}
