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

{{#chip_cluster_commands}}
/*
 * 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);
        MTRBaseCluster{{asUpperCamelCase clusterName}} * cluster = [[MTRBaseCluster{{asUpperCamelCase clusterName}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        __auto_type * params = [[MTR{{asUpperCamelCase clusterName}}Cluster{{asUpperCamelCase name}}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}}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}}
};

{{/chip_cluster_commands}}

{{#chip_server_cluster_attributes}}
{{#*inline "attribute"}}Attribute{{asUpperCamelCase name}}{{/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);
        MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        {{#if_is_fabric_scoped_struct type}}
        MTRReadParams * params = [[MTRReadParams alloc] init];
        if (mFabricFiltered.HasValue()) {
          params.filterByFabric = mFabricFiltered.Value();
        }
        {{/if_is_fabric_scoped_struct}}
        [cluster readAttribute{{asUpperCamelCase name}}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}}.{{asUpperCamelCase name}} response %@", [value description]);
        if (error != nil) {
          LogNSError("{{asUpperCamelCase parent.name}} {{asUpperCamelCase name}} 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);
        MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        MTRWriteParams * 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 writeAttribute{{asUpperCamelCase name}}WithValue:value params:params completion:^(NSError * _Nullable error) {
            if (error != nil) {
              LogNSError("{{asUpperCamelCase parent.name}} {{asUpperCamelCase name}} 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);
        MTRBaseCluster{{asUpperCamelCase parent.name}} * cluster = [[MTRBaseCluster{{asUpperCamelCase parent.name}} alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue];
        MTRSubscribeParams * 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}}.{{asUpperCamelCase name}} response %@", [value description]);
        SetCommandExitStatus(error);
         }];

        return CHIP_NO_ERROR;
    }
};

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

/*----------------------------------------------------------------------------*\
| Register all Clusters commands                                               |
\*----------------------------------------------------------------------------*/
{{#chip_client_clusters includeAll=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}}
        make_unique<{{asUpperCamelCase clusterName}}{{asUpperCamelCase name}}>(), //
        {{/chip_cluster_commands}}
        {{#chip_server_cluster_attributes}}
        {{#first}}
         make_unique<ReadAttribute>(Id), //
        {{/first}}
        make_unique<Read{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{#first}}
        make_unique<WriteAttribute>(Id), //
        {{/first}}
        {{#if isWritableAttribute}}
        make_unique<Write{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{#first}}
        make_unique<SubscribeAttribute>(Id), //
        {{/first}}
        {{#if isReportableAttribute}}
        make_unique<SubscribeAttribute{{asUpperCamelCase parent.name}}{{asUpperCamelCase name}}>(), //
        {{/if}}
        {{/chip_server_cluster_attributes}}
    };

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

    commands.Register(clusterName, clusterCommands);
}

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