{{> 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>

{{> clusters_header}}

{{#chip_client_clusters includeAll=true}}
{{#unless (wasRemoved (asUpperCamelCase name preserveAcronyms=true))}}
{{> cluster_header}}

{{#chip_cluster_commands}}
{{#unless (wasRemoved (asUpperCamelCase clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
/*
 * Command {{asUpperCamelCase name}}
 */
class {{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}: public ClusterCommand
{
public:
    {{asUpperCamelCase clusterName}}{{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}}
    {
        {{#chip_cluster_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}}
        {{/chip_cluster_command_arguments}}
        ClusterCommand::AddArguments();
    }

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

        dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL);
        __auto_type * cluster = [[MTRBaseCluster{{asUpperCamelCase clusterName preserveAcronyms=true}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTR{{asUpperCamelCase clusterName preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}}Params alloc] init];
        params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil;
        {{#chip_cluster_command_arguments}}
        {{>decodable_value target=(concat "params." (asStructPropertyName label)) source=(concat "mRequest." (asLowerCamelCase label)) cluster=parent.clusterName type=type depth=0}}
        {{/chip_cluster_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 clusterName preserveAcronyms=true}}Cluster{{asUpperCamelCase responseName}}Params * _Nullable values, NSError * _Nullable error) {
                    NSLog(@"Values: %@", values);
            {{else}}
                ^(NSError * _Nullable error) {
            {{/if}}
                    responsesNeeded--;
                    if (error != nil) {
                        mError = error;
                        LogNSError("Error", error);
                    }
                    if (responsesNeeded == 0) {
                        SetCommandExitStatus(mError);
                    }
                }];
        }
        return CHIP_NO_ERROR;
    }

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

{{/unless}}
{{/chip_cluster_commands}}

{{#chip_server_cluster_attributes}}
{{#unless (wasRemoved (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
{{#*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
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) ReadAttribute ({{asHex code 8}}) on endpoint %u", 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];
        {{#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) {
          LogNSError("{{asUpperCamelCase parent.name preserveAcronyms=true}} {{asUpperCamelCase name preserveAcronyms=true}} read Error", 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
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) WriteAttribute ({{asHex code 8}}) on endpoint %u", 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 (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_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);
            }
            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)}}
    chip::ByteSpan mValue;
    {{else if (isCharString type)}}
    chip::ByteSpan mValue;
    {{else}}
    {{chipType}} 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
    {
        ChipLogProgress(chipTool, "Sending cluster ({{asHex parent.code 8}}) ReportAttribute ({{asHex code 8}}) on endpoint %u", 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.resubscribeIfLost = 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]);
        SetCommandExitStatus(error);
         }];

        return CHIP_NO_ERROR;
    }
};

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

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

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

    commands_list clusterCommands = {
        make_unique<ClusterCommand>(Id), //
        {{#chip_cluster_commands}}
        {{#unless (wasRemoved (asUpperCamelCase clusterName preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
        make_unique<{{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}>(), //
        {{/unless}}
        {{/chip_cluster_commands}}
        {{#chip_server_cluster_attributes}}
        {{#first}}
         make_unique<ReadAttribute>(Id), //
        {{/first}}
        {{#unless (wasRemoved (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        make_unique<Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/unless}}
        {{#first}}
        make_unique<WriteAttribute>(Id), //
        {{/first}}
        {{#unless (wasRemoved (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if isWritableAttribute}}
        make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/unless}}
        {{#first}}
        make_unique<SubscribeAttribute>(Id), //
        {{/first}}
        {{#unless (wasRemoved (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if isReportableAttribute}}
        make_unique<SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/unless}}
        {{/chip_server_cluster_attributes}}
        {{#zcl_events}}
        {{#first}}
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
        {{/first}}
        {{/zcl_events}}
    };

    commands.Register(clusterName, clusterCommands);
}
{{/unless}}
{{/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>(chip::kInvalidClusterId, true), //
        make_unique<SubscribeEvent>(),     //
    };

    commands.Register(clusterName, clusterCommands);
}

void registerClusters(Commands & commands)
{
    registerClusterAny(commands);
{{#chip_client_clusters includeAll=true}}
    {{#unless (wasRemoved (asUpperCamelCase name preserveAcronyms=true))}}
    registerCluster{{asUpperCamelCase name}}(commands);
    {{/unless}}
{{/chip_client_clusters}}
}
