{{> header excludeZapComment=true}}

#import <Foundation/Foundation.h>

#import "MTRClusterStateCacheContainer_Internal.h"
#import "MTRBaseClusters_internal.h"
#import "MTRBaseDevice.h"
#import "MTRBaseDevice_Internal.h"
#import "MTRCallbackBridge_internal.h"
#import "MTRCluster_internal.h"
#import "MTRStructsObjc.h"
#import "MTRCommandPayloadsObjc.h"
#import "MTRBaseClustersCpp_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;

// NOLINTBEGIN(clang-analyzer-cplusplus.NewDeleteLeaks): Linter is unable to locate the delete on these objects.
{{#chip_client_clusters includeAll=true}}
@implementation MTRBaseCluster{{asUpperCamelCase name}}

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

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

{{#chip_cluster_commands}}
{{#*inline "callbackName"}}{{#if hasSpecificResponse}}{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase responseName}}{{else}}CommandSuccess{{/if}}{{/inline}}
{{#unless (hasArguments)}}
- (void){{asLowerCamelCase name}}WithCompletion:({{>command_completion_type command=.}})completion
{
  [self {{asLowerCamelCase name}}WithParams:nil completion:completion];
}
{{/unless}}
- (void){{asLowerCamelCase name}}WithParams: (MTR{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Params * {{#unless (commandHasRequiredField .)}}_Nullable{{/unless}})params completion:({{>command_completion_type command=.}})completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTR{{>callbackName}}CallbackBridge(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,
      {{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. }}
        ^(id _Nullable value, NSError * _Nullable error) {
          completion(error);
        },
      {{/if}}
      ^(ExchangeManager & exchangeManager, const SessionHandle & session, {{>callbackName}}CallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
        auto * typedBridge = static_cast<MTR{{>callbackName}}CallbackBridge *>(bridge);
        chip::Optional<uint16_t> timedInvokeTimeoutMs;
        ListFreer listFreer;
        {{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::Type request;
        if (params != nil) {
          if (params.timedInvokeTimeoutMs != nil) {
            timedInvokeTimeoutMs.SetValue(params.timedInvokeTimeoutMs.unsignedShortValue);
          }
        }
        {{#if mustUseTimedInvoke}}
        if (!timedInvokeTimeoutMs.HasValue()) {
          timedInvokeTimeoutMs.SetValue(10000);
        }
        {{/if}}
        {{#chip_cluster_command_arguments}}
          {{#first}}
            {{#unless (commandHasRequiredField parent)}}
            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 (commandHasRequiredField parent)}}
            }
           {{/unless}}
          {{/last}}
        {{/chip_cluster_command_arguments}}

        return MTRStartInvokeInteraction(typedBridge, request, exchangeManager, session, successCb, failureCb, self->_endpoint, timedInvokeTimeoutMs);
    });
    std::move(*bridge).DispatchAction(self.device);
}
{{/chip_cluster_commands}}

{{#chip_server_cluster_attributes}}
{{#*inline "attribute"}}Attribute{{asUpperCamelCase name}}{{/inline}}
- (void)read{{>attribute}}With
{{~#if_is_fabric_scoped_struct type~}}
  Params:(MTRReadParams * _Nullable)params completion:
{{~else~}}
  Completion:
{{~/if_is_fabric_scoped_struct~}}
(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion
{
    {{~#if_is_fabric_scoped_struct type}}
    // Make a copy of params before we go async.
    params = [params copy];
    {{else}}
    MTRReadParams * params = [[MTRReadParams alloc] init];
    {{/if_is_fabric_scoped_struct~}}
    using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
    return MTRReadAttribute<MTR{{>attribute_data_callback_name}}CallbackBridge,
                         {{asObjectiveCClass type parent.name}},
                         TypeInfo::DecodableType>(params, completion, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

{{#if isWritableAttribute}}
{{#*inline "callbackName"}}DefaultSuccess{{/inline}}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completion:(MTRStatusCompletion)completion
{
  [self write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:nil completion:completion];
}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion
{
    // Make a copy of params before we go async.
    params = [params copy];
    value = [value copy];

    auto * bridge = new MTR{{>callbackName}}CallbackBridge(self.callbackQueue,
      {{! 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. }}
      ^(id _Nullable ignored, NSError * _Nullable error) {
        completion(error);
      },
      ^(ExchangeManager & exchangeManager, const SessionHandle & session, {{>callbackName}}CallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
        chip::Optional<uint16_t> timedWriteTimeout;
        if (params != nil) {
          if (params.timedWriteTimeout != nil){
            timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue);
          }
        }
        {{#if mustUseTimedInvoke}}
        if (!timedWriteTimeout.HasValue()) {
          timedWriteTimeout.SetValue(10000);
        }
        {{/if}}

        ListFreer listFreer;
        using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
        TypeInfo::Type cppValue;
        {{>encode_value target="cppValue" source="value" cluster=parent.name errorCode="return CHIP_ERROR_INVALID_ARGUMENT;" depth=0}}

        chip::Controller::{{asUpperCamelCase parent.name}}Cluster cppCluster(exchangeManager, session, self->_endpoint);
        return cppCluster.WriteAttribute<TypeInfo>(cppValue, bridge, successCb, failureCb, timedWriteTimeout);
    });
    std::move(*bridge).DispatchAction(self.device);
}

{{/if}}
{{#if isReportableAttribute}}
- (void) subscribe{{>attribute}}WithParams:(MTRSubscribeParams * _Nonnull)params
subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished
reportHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))reportHandler
{
    using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
    MTRSubscribeAttribute<MTR{{>attribute_data_callback_name}}CallbackSubscriptionBridge, {{asObjectiveCClass type parent.name}}, TypeInfo::DecodableType>(params, subscriptionEstablished, reportHandler, self.callbackQueue, self.device, self->_endpoint, TypeInfo::GetClusterId(), TypeInfo::GetAttributeId());
}

+ (void) read{{>attribute}}WithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint  queue:(dispatch_queue_t)queue completion:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completion
{
    auto * bridge = new MTR{{>attribute_data_callback_name}}CallbackBridge(queue, completion);
    std::move(*bridge).DispatchLocalAction(^({{>attribute_data_callback_name}}Callback successCb, MTRErrorCallback failureCb) {
          if (clusterStateCacheContainer.cppClusterStateCache) {
              chip::app::ConcreteAttributePath path;
              using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
              path.mEndpointId = static_cast<chip::EndpointId>([endpoint unsignedShortValue]);
              path.mClusterId = TypeInfo::GetClusterId();
              path.mAttributeId = TypeInfo::GetAttributeId();
              TypeInfo::DecodableType value;
              CHIP_ERROR err = clusterStateCacheContainer.cppClusterStateCache->Get<TypeInfo>(path, value);
              if (err == CHIP_NO_ERROR)
              {
                successCb(bridge, value);
              }
              return err;
          }
          return CHIP_ERROR_NOT_FOUND;
      });
}

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

@end
{{#if (isStrEqual (asUpperCamelCase name) "UnitTesting")}}

@implementation MTRBaseClusterTestCluster
@end
{{/if}}

@implementation MTRBaseCluster{{compatClusterNameRemapping name}} (Deprecated)

{{#chip_cluster_commands}}
- (void){{asLowerCamelCase name}}WithParams:(MTR{{compatClusterNameRemapping parent.name}}Cluster{{asUpperCamelCase name}}Params * {{#unless (commandHasRequiredField .)}}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=. compatRemapClusterName=true}})completionHandler
{
  [self {{asLowerCamelCase name}}WithParams:params completion:
    {{#if hasSpecificResponse}}
    ^(MTR{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase responseName}}Params * _Nullable data, NSError * _Nullable error) {
      // Cast is safe because subclass does not add any selectors.
      completionHandler(static_cast<MTR{{compatClusterNameRemapping parent.name}}Cluster{{asUpperCamelCase responseName}}Params *>(data), error);
    }
    {{else}}
    completionHandler
    {{/if}}
    ];
}
{{#unless (hasArguments)}}
- (void){{asLowerCamelCase name}}WithCompletionHandler:({{>command_completion_type command=. compatRemapClusterName=true}})completionHandler
{
  [self {{asLowerCamelCase name}}WithParams:nil completionHandler:completionHandler];
}
{{/unless}}
{{/chip_cluster_commands}}

{{#chip_server_cluster_attributes}}
{{!Backwards compat for now: Treat DeviceTypeList as DeviceList.  Ideally we would have both, not just DeviceList. }}
{{#*inline "attribute"}}Attribute{{#if (isStrEqual (asUpperCamelCase parent.name) "Descriptor")}}{{#if (isStrEqual (asUpperCamelCase name) "DeviceTypeList")}}DeviceList{{else}}{{asUpperCamelCase name}}{{/if}}{{else}}{{asUpperCamelCase name}}{{/if}}{{/inline}}
{{! TODO: We need a better setup for the API_AVALABLE annotations here; this does not scale at all sanely. }}
- (void)read{{>attribute}}With
{{~#if_is_fabric_scoped_struct type~}}
  Params:(MTRReadParams * _Nullable)params completionHandler:
{{~else~}}
  CompletionHandler:
{{~/if_is_fabric_scoped_struct~}}
(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler
{
  [self 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) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<{{asObjectiveCClass type parent.name compatRemapClusterName=true}} *>(value), error);
      }];
}
{{#if isWritableAttribute}}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value completionHandler:(MTRStatusCompletion)completionHandler
{
  [self writeAttribute{{asUpperCamelCase name}}WithValue:value params:nil completion:completionHandler];
}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name compatRemapClusterName=true}})value params:(MTRWriteParams * _Nullable)params completionHandler:(MTRStatusCompletion)completionHandler
{
  [self writeAttribute{{asUpperCamelCase name}}WithValue:value params:params completion:completionHandler];
}
{{/if}}
{{#if isReportableAttribute}}
- (void) subscribe{{>attribute}}WithMinInterval:(NSNumber * _Nonnull)minInterval  maxInterval:(NSNumber * _Nonnull)maxInterval
       params:(MTRSubscribeParams * _Nullable)params
subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablishedHandler reportHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))reportHandler
{
  MTRSubscribeParams * _Nullable subscribeParams = [params copy];
  if (subscribeParams == nil) {
      subscribeParams = [[MTRSubscribeParams alloc] initWithMinInterval:minInterval maxInterval:maxInterval];
  } else {
      subscribeParams.minInterval = minInterval;
      subscribeParams.maxInterval = maxInterval;
  }
  [self subscribeAttribute{{asUpperCamelCase name}}WithParams:subscribeParams subscriptionEstablished:subscriptionEstablishedHandler reportHandler:
     ^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
       // Cast is safe because subclass does not add any selectors.
       reportHandler(static_cast<{{asObjectiveCClass type parent.name compatRemapClusterName=true}} *>(value), error)     ;
     }];
}
+ (void) read{{>attribute}}WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completionHandler:(void (^)({{asObjectiveCClass type parent.name compatRemapClusterName=true}} * _Nullable value, NSError * _Nullable error))completionHandler
{
  [self readAttribute{{asUpperCamelCase name}}WithClusterStateCache:attributeCacheContainer.realContainer endpoint:endpoint queue:queue completion:
      ^({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error) {
        // Cast is safe because subclass does not add any selectors.
        completionHandler(static_cast<{{asObjectiveCClass type parent.name compatRemapClusterName=true}} *>(value), error);
      }];
}
{{/if}}
{{/chip_server_cluster_attributes}}

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

@end

{{/chip_client_clusters}}

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