{{> header excludeZapComment=true}}

#import <Foundation/Foundation.h>

#import "MTRAttributeCacheContainer_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"

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

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

        chip::Controller::{{asUpperCamelCase parent.name}}Cluster cppCluster(exchangeManager, session, self->_endpoint);
        return cppCluster.InvokeCommand(request, bridge, successCb, failureCb, 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];
    {{/if_is_fabric_scoped_struct~}}
    auto * bridge = new MTR{{>attribute_data_callback_name}}CallbackBridge(self.callbackQueue,
      {{! This treats completion as taking an id for the data.  This is
          not great from a type-safety perspective, of course. }}
      completion,
      ^(ExchangeManager & exchangeManager, const SessionHandle & session, {{>attribute_data_callback_name}}Callback successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
          using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;
          chip::Controller::{{asUpperCamelCase parent.name}}Cluster cppCluster(exchangeManager, session, self->_endpoint);
          return cppCluster.ReadAttribute<TypeInfo>(bridge, successCb, failureCb
          {{~#if_is_fabric_scoped_struct type~}}
          , params.filterByFabric
          {{~/if_is_fabric_scoped_struct~}}
          );
      });
    std::move(*bridge).DispatchAction(self.device);
}

{{#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
{
    // Make a copy of params before we go async.
    params = [params copy];
    auto * bridge = new MTR{{>attribute_data_callback_name}}CallbackSubscriptionBridge(self.callbackQueue,
      {{! This treats reportHandler as taking an id for the data.  This is
          not great from a type-safety perspective, of course. }}
      reportHandler,
      ^(ExchangeManager & exchangeManager, const SessionHandle & session,  {{>attribute_data_callback_name}}Callback successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) {
          auto * typedBridge = static_cast<MTR{{>attribute_data_callback_name}}CallbackSubscriptionBridge *>(bridge);
          if (!params.resubscribeIfLost) {
              // We don't support disabling auto-resubscribe.
              return CHIP_ERROR_INVALID_ARGUMENT;
          }
          using TypeInfo = {{asUpperCamelCase parent.name}}::Attributes::{{asUpperCamelCase name}}::TypeInfo;

          chip::Controller::{{asUpperCamelCase parent.name}}Cluster cppCluster(exchangeManager, session, self->_endpoint);
          CHIP_ERROR err = cppCluster.SubscribeAttribute<TypeInfo>(bridge, successCb, failureCb, [params.minInterval unsignedShortValue], [params.maxInterval unsignedShortValue], MTR{{>attribute_data_callback_name}}CallbackSubscriptionBridge::OnSubscriptionEstablished, nil,
              params.filterByFabric,
              !params.replaceExistingSubscriptions,
              chip::NullOptional,
              [typedBridge](void) { typedBridge->OnDone(); }
          );
          if (err == CHIP_NO_ERROR) {
              // Now that we kicked off the subscribe, flag our callback bridge
              // to stay alive until we get an OnDone.
              typedBridge->KeepAliveOnCallback();
          }
          return err;
      }, subscriptionEstablished);
    std::move(*bridge).DispatchAction(self.device);
}

+ (void) read{{>attribute}}WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer 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 (attributeCacheContainer.cppAttributeCache) {
              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 = attributeCacheContainer.cppAttributeCache->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

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

{{#chip_cluster_commands}}
- (void){{asLowerCamelCase name}}WithParams:(MTR{{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Params * {{#unless (commandHasRequiredField .)}}_Nullable{{/unless}})params completionHandler:({{>command_completion_type command=.}})completionHandler
{
  [self {{asLowerCamelCase name}}WithParams:params completion:completionHandler];
}
{{#unless (hasArguments)}}
- (void){{asLowerCamelCase name}}WithCompletionHandler:({{>command_completion_type command=.}})completionHandler
{
  [self {{asLowerCamelCase name}}WithParams:nil completion: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}} * _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}}completionHandler];
}
{{#if isWritableAttribute}}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})value completionHandler:(MTRStatusCompletion)completionHandler
{
  [self writeAttribute{{asUpperCamelCase name}}WithValue:value params:nil completion:completionHandler];
}
- (void)write{{>attribute}}WithValue:({{asObjectiveCType type parent.name}})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}} * _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:reportHandler];
}
+ (void) read{{>attribute}}WithAttributeCache:(MTRAttributeCacheContainer *)attributeCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completionHandler:(void (^)({{asObjectiveCClass type parent.name}} * _Nullable value, NSError * _Nullable error))completionHandler
{
  [self readAttribute{{asUpperCamelCase name}}WithAttributeCache:attributeCacheContainer endpoint:endpoint queue:queue completion:completionHandler];
}
{{/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)
