{{> header excludeZapComment=true}}

#import <Foundation/Foundation.h>

#import "MTRAsyncCallbackWorkQueue.h"
#import "MTRBaseClusterUtils.h"
#import "MTRBaseDevice_Internal.h"
#import "MTRClusterConstants.h"
#import "MTRClusters_Internal.h"
#import "MTRDevice_Internal.h"
#import "MTRCallbackBridge.h"
#import "MTRCluster_Internal.h"
#import "MTRStructsObjc.h"
#import "MTRCommandPayloadsObjc.h"
#import "MTRLogging_Internal.h"

#include <lib/support/CHIPListUtils.h>
#include <platform/CHIPDeviceLayer.h>
#include <type_traits>

using chip::Callback::Callback;
using chip::Callback::Cancelable;
using namespace chip::app::Clusters;
using chip::Messaging::ExchangeManager;
using chip::SessionHandle;
using chip::Optional;
using chip::System::Clock::Timeout;
using chip::System::Clock::Seconds16;

static void MTRClustersLogEnqueue(NSString *logPrefix, MTRAsyncCallbackWorkQueue *workQueue) {
    MTR_LOG_DEFAULT("%@ enqueueWorkItem %@", logPrefix, workQueue);
}

static void MTRClustersLogDequeue(NSString *logPrefix, MTRAsyncCallbackWorkQueue *workQueue) {
    MTR_LOG_DEFAULT("%@ dequeueWorkItem %@", logPrefix, workQueue);
}

static void MTRClustersLogCompletion(NSString *logPrefix, id value, NSError *error) {
    // Log the data at the INFO level (not usually persisted permanently),
    // but make sure we log the work completion at the DEFAULT level.
    MTR_LOG_INFO("%@ received response: %@ error: %@", logPrefix, value, error);
    MTR_LOG_DEFAULT("%@ endWork", logPrefix);
}

// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks): Linter is unable to locate the delete on these objects.
{{#zcl_clusters}}
{{#if (isSupported (asUpperCamelCase name preserveAcronyms=true))}}
@implementation MTRCluster{{asUpperCamelCase name preserveAcronyms=true}}

- (instancetype)initWithDevice:(MTRDevice *)device endpointID:(NSNumber *)endpointID queue:(dispatch_queue_t)queue
{
    if (self = [super initWithQueue:queue]) {
        if (device == nil) {
            return nil;
        }

        {{!TODO consider range-checking the incoming number to make sure it's
                actually in the uint16_t range}}
        _endpoint = [endpointID unsignedShortValue];
        _device = device;
    }
    return self;
}

{{#zcl_commands}}
{{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }}
{{#*inline "commandImpl"}}
{{! This is used as the implementation for both the new-name and old-name bits, so check for both here. }}
{{#if (or (isSupported cluster command=command)
          (isSupported (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}}
{{#*inline "callbackName"}}{{#if hasSpecificResponse}}{{cluster}}Cluster{{asUpperCamelCase responseName preserveAcronyms=true}}{{else}}CommandSuccess{{/if}}{{/inline}}
{{#*inline "paramsType"}}
{{#unless (isSupported cluster command=command)}}
MTR{{compatClusterNameRemapping parent.name}}Cluster{{compatCommandNameRemapping parent.name name}}Params
{{else}}
MTR{{cluster}}Cluster{{command}}Params
{{/unless}}
{{/inline}}
{{#*inline "clusterId"}}
{{#unless (isSupported cluster command=command)}}
{{asMEI ../manufacturerCode ../code}}
{{else}}
MTRClusterIDType{{cluster}}ID
{{/unless}}
{{/inline}}
{{#*inline "commandId"}}
{{#unless (isSupported cluster command=command)}}
{{asMEI manufacturerCode code}}
{{else}}
MTRCommandIDTypeCluster{{cluster}}Command{{command}}ID
{{/unless}}
{{/inline}}
{{#unless hasArguments}}
- (void){{asLowerCamelCase name}}WithExpectedValues:(NSArray<NSDictionary<NSString *, id> *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion
{
  [self {{asLowerCamelCase name}}WithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completion:completion];
}
{{/unless}}
- (void){{asLowerCamelCase name}}WithParams: ({{> paramsType}} * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray<NSDictionary<NSString *, id> *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:({{>command_completion_type command=.}})completion
{
    NSString * logPrefix = [NSString stringWithFormat:@"MTRDevice command %u %u %u %u", self.device.deviceController.fabricIndex, _endpoint, (unsigned int){{> clusterId}}, (unsigned int){{> commandId}}];
    // Make a copy of params before we go async.
    params = [params copy];
    NSNumber *timedInvokeTimeoutMsParam = params.timedInvokeTimeoutMs;
    if (timedInvokeTimeoutMsParam) {
      timedInvokeTimeoutMsParam = MTRClampedNumber(timedInvokeTimeoutMsParam, @(1), @(UINT16_MAX));
    }
    MTRAsyncCallbackQueueWorkItem * workItem = [[MTRAsyncCallbackQueueWorkItem alloc] initWithQueue:self.device.queue];
    MTRAsyncCallbackReadyHandler readyHandler = ^(MTRDevice * device, NSUInteger retryCount) {
        MTRClustersLogDequeue(logPrefix, self.device.asyncCallbackWorkQueue);
        MTRBaseDevice *baseDevice = [[MTRBaseDevice alloc] initWithNodeID:self.device.nodeID controller:self.device.deviceController];
        auto * bridge = new MTR{{>callbackName}}CallbackBridge(self.device.queue,
          ^(id _Nullable value, NSError * _Nullable error) {
            MTRClustersLogCompletion(logPrefix, value, error);
            dispatch_async(self.callbackQueue, ^{
          {{#if hasSpecificResponse}}
            {{! This treats completion as taking an id for the data.  This is
                not great from a type-safety perspective, of course. }}
            completion(value, error);
          {{else}}
            {{! For now, don't change the bridge API; instead just use an adapter
                to invoke our completion handler. This is not great from a
                type-safety perspective, of course. }}
            completion(error);
          {{/if}}
            });
            [workItem endWork];
          },
          ^(ExchangeManager & exchangeManager, const SessionHandle & session, {{>callbackName}}CallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
            auto * typedBridge = static_cast<MTR{{>callbackName}}CallbackBridge *>(bridge);
            Optional<uint16_t> timedInvokeTimeoutMs;
            Optional<Timeout> invokeTimeout;
            ListFreer listFreer;
            {{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Type request;
            if (timedInvokeTimeoutMsParam != nil) {
              timedInvokeTimeoutMs.SetValue(timedInvokeTimeoutMsParam.unsignedShortValue);
            }
            if (params != nil) {
              if (params.serverSideProcessingTimeout != nil) {
                // Clamp to a number of seconds that will not overflow 32-bit
                // int when converted to ms.
                auto * serverSideProcessingTimeout = MTRClampedNumber(params.serverSideProcessingTimeout, @(0), @(UINT16_MAX));
                invokeTimeout.SetValue(Seconds16(serverSideProcessingTimeout.unsignedShortValue));
              }
            }
            {{#if mustUseTimedInvoke}}
            if (!timedInvokeTimeoutMs.HasValue()) {
              timedInvokeTimeoutMs.SetValue(10000);
            }
            {{/if}}
            {{#zcl_command_arguments}}
              {{#first}}
                {{#unless parent.commandHasRequiredField}}
                if (params != nil) {
                {{/unless}}
              {{/first}}
              {{>encode_value target=(concat "request." (asLowerCamelCase label)) source=(concat "params." (asStructPropertyName label)) cluster=parent.parent.name errorCode="return CHIP_ERROR_INVALID_ARGUMENT;" depth=0}}
              {{#last}}
                {{#unless parent.commandHasRequiredField}}
                }
               {{/unless}}
              {{/last}}
            {{/zcl_command_arguments}}

            return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint, timedInvokeTimeoutMs, invokeTimeout);
        });
        std::move(*bridge).DispatchAction(baseDevice);
    };
    workItem.readyHandler = readyHandler;
    MTRClustersLogEnqueue(logPrefix, self.device.asyncCallbackWorkQueue);
    [self.device.asyncCallbackWorkQueue enqueueWorkItem:workItem];

    if (!expectedValueIntervalMs || ([expectedValueIntervalMs compare:@(0)] == NSOrderedAscending)) {
      expectedValues = nil;
    } else {
      expectedValueIntervalMs = MTRClampedNumber(expectedValueIntervalMs, @(1), @(UINT32_MAX));
    }
    if (expectedValues) {
      [self.device setExpectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs];
    }
}
{{/if}}
{{/inline}}
{{#if (is_str_equal source 'client')}}
{{> commandImpl cluster=(asUpperCamelCase parent.name preserveAcronyms=true)
                command=(asUpperCamelCase name preserveAcronyms=true)}}
{{/if}}
{{/zcl_commands}}

{{#zcl_attributes_server}}
{{! This is used as the implementation for both the new-name and old-name bits, so check for both here. }}
{{#if (and
        (or clusterRef
            (isSupported "" globalAttribute=(asUpperCamelCase label preserveAcronyms=true)))
        (or (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) attribute=(asUpperCamelCase name preserveAcronyms=true))
            (and (isSupported (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name))
                 (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) attribute=(compatAttributeNameRemapping parent.name name)))))}}
{{#*inline "cluster"}}{{asUpperCamelCase parent.name preserveAcronyms=true}}{{/inline}}
{{#*inline "attribute"}}Attribute{{asUpperCamelCase name preserveAcronyms=true}}{{/inline}}
- (NSDictionary<NSString *, id> *)read{{>attribute}}WithParams:(MTRReadParams * _Nullable)params {
    return [self.device readAttributeWithEndpointID:@(_endpoint) clusterID:@(MTRClusterIDType{{>cluster}}ID) attributeID:@(MTRAttributeIDTypeCluster{{>cluster}}{{>attribute}}ID) params:params];
}

{{#if isWritableAttribute}}
{{#*inline "callbackName"}}DefaultSuccess{{/inline}}
- (void)write{{>attribute}}WithValue:(NSDictionary<NSString *, id> *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs
{
  [self write{{>attribute}}WithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil];
}
- (void)write{{>attribute}}WithValue:(NSDictionary<NSString *, id> *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params
{
    NSNumber *timedWriteTimeout = params.timedWriteTimeout;
    {{#if mustUseTimedInvoke}}
    if (!timedWriteTimeout) {
        timedWriteTimeout = @(10000);
    }
    {{/if}}

    [self.device writeAttributeWithEndpointID:@(_endpoint) clusterID:@(MTRClusterIDType{{>cluster}}ID) attributeID:@(MTRAttributeIDTypeCluster{{>cluster}}{{>attribute}}ID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout];
}

{{/if}}

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

@end
{{/if}}
{{#unless (isStrEqual (asUpperCamelCase name preserveAcronyms=true) (compatClusterNameRemapping name))}}
{{#if (isSupported (compatClusterNameRemapping name))}}
@implementation MTRCluster{{compatClusterNameRemapping name}}
@end
{{/if}}
{{/unless}}

{{#if (and (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping name))
           (isSupported (compatClusterNameRemapping name)))}}
@implementation MTRCluster{{compatClusterNameRemapping name}} (Deprecated)

- (instancetype)initWithDevice:(MTRDevice *)device endpoint:(uint16_t)endpoint queue:(dispatch_queue_t)queue
{
    return [self initWithDevice:device endpointID:@(endpoint) queue:queue];
}

{{#zcl_commands}}
{{#if (is_str_equal source 'client')}}
{{! Takes two arguments: cluster name and command name, plus the ambient state where the command is "this" }}
{{#*inline "commandImpl"}}
{{#if (isSupported cluster command=command)}}
- (void){{asLowerCamelCase command}}WithParams:(MTR{{cluster}}Cluster{{command}}Params * {{#unless commandHasRequiredField}}_Nullable{{/unless}})params expectedValues:(NSArray<NSDictionary<NSString *, id> *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler
{
  [self {{asLowerCamelCase name}}WithParams:params expectedValues:expectedDataValueDictionaries expectedValueInterval:expectedValueIntervalMs completion:
      {{#if hasSpecificResponse}}
    ^(MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase responseName preserveAcronyms=true}}Params * _Nullable data, NSError * _Nullable error) {
      // Cast is safe because subclass does not add any selectors.
      completionHandler(static_cast<MTR{{cluster}}Cluster{{compatCommandNameRemapping parent.name responseName}}Params *>(data), error);
    }
    {{else}}
    completionHandler
    {{/if}}
    ];
}
{{#unless hasArguments}}
- (void){{asLowerCamelCase command}}WithExpectedValues:(NSArray<NSDictionary<NSString *, id> *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completionHandler:({{>command_completion_type command=. compatRemapNames=true}})completionHandler
{
  [self {{asLowerCamelCase command}}WithParams:nil expectedValues:expectedValues expectedValueInterval:expectedValueIntervalMs completionHandler:completionHandler];
}
{{/unless}}
{{/if}}
{{/inline}}
{{> commandImpl cluster=(compatClusterNameRemapping parent.name)
                command=(compatCommandNameRemapping parent.name name)}}
{{/if}}
{{/zcl_commands}}
{{~#zcl_attributes_server}}
{{~#*inline "attributeImpls"}}
{{#if (and (not (isStrEqual attribute (asUpperCamelCase name preserveAcronyms=true)))
           (isSupported (compatClusterNameRemapping parent.name) attribute=attribute))}}
- (NSDictionary<NSString *, id> *)readAttribute{{attribute}}WithParams:(MTRReadParams * _Nullable)params
{
  return [self readAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithParams:params];
}
{{#if isWritableAttribute}}
- (void)writeAttribute{{attribute}}WithValue:(NSDictionary<NSString *, id> *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs
{
  [self writeAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs];
}
- (void)writeAttribute{{attribute}}WithValue:(NSDictionary<NSString *, id> *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params
{
  [self writeAttribute{{asUpperCamelCase name preserveAcronyms=true}}WithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:params];
}
{{/if}}
{{/if}}
{{/inline~}}
{{> attributeImpls attribute=(compatAttributeNameRemapping parent.name name)}}
{{/zcl_attributes_server}}
@end
{{/if}}

{{/zcl_clusters}}

// NOLINTEND(clang-analyzer-cplusplus.NewDeleteLeaks)
