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

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

{{#zcl_commands}}
{{#if (is_str_equal source 'client')}}
{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
/*
 * 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_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(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 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}}
        {{>decodable_value target=(concat "params." (asStructPropertyName label)) source=(concat "mRequest." (asLowerCamelCase label)) cluster=parent.parent.name type=type depth=0}}
        {{/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);
            {{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 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}}
{{/if}}
{{/zcl_commands}}

{{#zcl_attributes_server removeKeys='isOptional'}}
{{#if (isSupported (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}}
    {{as_underlying_zcl_type type}} 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.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]);
        SetCommandExitStatus(error);
         }];

        return CHIP_NO_ERROR;
    }
};

{{/if}}
{{/if}}
{{/zcl_attributes_server}}
{{/if}}
{{/zcl_clusters}}

/*----------------------------------------------------------------------------*\
| Register all Clusters commands                                               |
\*----------------------------------------------------------------------------*/
{{#zcl_clusters}}
{{#if (isSupported (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), //
        {{#zcl_commands}}
        {{#if (is_str_equal source 'client')}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
        make_unique<{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/if}}
        {{/zcl_commands}}
        {{#zcl_attributes_server removeKeys='isOptional'}}
        {{#first}}
         make_unique<ReadAttribute>(Id), //
        {{/first}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        make_unique<Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{#first}}
        make_unique<WriteAttribute>(Id), //
        {{/first}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if isWritableAttribute}}
        make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/if}}
        {{#first}}
        make_unique<SubscribeAttribute>(Id), //
        {{/first}}
        {{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))}}
        {{#if isReportableAttribute}}
        make_unique<SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/if}}
        {{/zcl_attributes_server}}
        {{#zcl_events}}
        {{#first}}
        make_unique<ReadEvent>(Id), //
        make_unique<SubscribeEvent>(Id), //
        {{/first}}
        {{/zcl_events}}
    };

    commands.Register(clusterName, clusterCommands);
}
{{/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.Register(clusterName, clusterCommands);
}

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