{{> 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("{{asDelimitedCommand 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}}", {{asTypeMinValue type}}, {{asTypeMaxValue type}}, &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 endpoint: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 completionHandler:
            {{#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("{{asDelimitedCommand (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 endpoint:endpointId queue:callbackQueue];
        {{#if_is_fabric_scoped_struct type}}
        MTRReadParams * params = [[MTRReadParams alloc] init];
        params.fabricFiltered = mFabricFiltered.HasValue() ? [NSNumber numberWithBool:mFabricFiltered.Value()] : nil;
        {{/if_is_fabric_scoped_struct}}
        [cluster readAttribute{{asUpperCamelCase name}}With
        {{~#if_is_fabric_scoped_struct type~}}
        Params:params completionHandler:
        {{~else~}}
        CompletionHandler:
        {{~/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("{{asDelimitedCommand (asUpperCamelCase name)}}"){{#if_chip_complex}}, mComplex(&mValue){{/if_chip_complex}}
    {
        AddArgument("attr-name", "{{asDelimitedCommand (asUpperCamelCase name)}}");
        {{#if_chip_complex}}
        AddArgument("attr-value", &mComplex);
        {{else if (isString type)}}
        AddArgument("attr-value", &mValue);
        {{else}}
        AddArgument("attr-value", {{asTypeMinValue type}}, {{asTypeMaxValue type}}, &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 endpoint: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 completionHandler:^(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("{{asDelimitedCommand (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 endpoint:endpointId queue:callbackQueue];
        MTRSubscribeParams * params = [[MTRSubscribeParams alloc] init];
        params.keepPreviousSubscriptions = mKeepSubscriptions.HasValue() ? [NSNumber numberWithBool:mKeepSubscriptions.Value()] : nil;
        params.fabricFiltered = mFabricFiltered.HasValue() ? [NSNumber numberWithBool:mFabricFiltered.Value()] : nil;
        [cluster subscribe{{>attribute}}WithMinInterval:[NSNumber numberWithUnsignedInt:mMinInterval]
                                            maxInterval:[NSNumber numberWithUnsignedInt:mMaxInterval]
                                                 params: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}}
}
