{{> header excludeZapComment=true}}

#import "MTRCommandPayloadsObjc.h"
#import "MTRCommandPayloads_Internal.h"
#import "MTRBaseDevice_Internal.h"
#import "MTRError_Internal.h"
#import "MTRLogging_Internal.h"

#include <lib/core/TLV.h>
#include <app/data-model/Decode.h>

NS_ASSUME_NONNULL_BEGIN

{{#zcl_clusters}}
{{#zcl_commands}}
{{#*inline "completeImpl"}}
{{#if (isSupported cluster command=command isForCommandPayload=true)}}
@implementation MTR{{cluster}}Cluster{{command}}Params
- (instancetype)init
{
  if (self = [super init]) {
{{#zcl_command_arguments}}

    {{>init_struct_member label=label type=type cluster=parent.parent.name}}
{{/zcl_command_arguments}}
{{#if (or (isStrEqual source "client")
          (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}}
    _timedInvokeTimeoutMs = nil;
{{/if}}
{{#if (isStrEqual source "client")}}
    _serverSideProcessingTimeout = nil;
{{/if}}
  }
  return self;
}

- (id)copyWithZone:(NSZone * _Nullable)zone;
{
  auto other = [[MTR{{cluster}}Cluster{{command}}Params alloc] init];

  {{#zcl_command_arguments}}
  other.{{asStructPropertyName label}} = self.{{asStructPropertyName label}};
  {{/zcl_command_arguments}}
{{#if (or (isStrEqual source "client")
          (wasIntroducedBeforeRelease "First major API revamp" (compatClusterNameRemapping parent.name) command=(compatCommandNameRemapping parent.name name)))}}
  other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs;
{{/if}}
{{#if (isStrEqual source "client")}}
  other.serverSideProcessingTimeout = self.serverSideProcessingTimeout;
{{/if}}

  return other;
}

- (NSString *)description
{
  NSString *descriptionString = [NSString stringWithFormat:@"<%@: {{#zcl_command_arguments}}{{asStructPropertyName label}}:%@; {{/zcl_command_arguments}}>", NSStringFromClass([self class]) {{#zcl_command_arguments}},{{#if isArray}}_{{asStructPropertyName label}}{{else if (isOctetString type)}}[_{{asStructPropertyName label}} base64EncodedStringWithOptions:0]{{else}}_{{asStructPropertyName label}}{{/if}}{{/zcl_command_arguments}}];
  return descriptionString;
}
{{#zcl_command_arguments}}
{{#if (and includeRenamedProperties
           (hasOldName ../cluster command=../command commandField=(asStructPropertyName label)))}}

{{> renamed_struct_field_impl cluster=parent.parent.name type=type newName=label oldName=(oldName ../cluster command=../command commandField=(asStructPropertyName label))}}
{{/if}}
{{/zcl_command_arguments}}

{{#if (isStrEqual source "server")}}
- (nullable instancetype)initWithResponseValue:(NSDictionary<NSString *, id> *)responseValue
                                         error:(NSError * __autoreleasing *)error
{
  if (!(self = [super init])) {
    return nil;
  }

  using DecodableType = chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::DecodableType;
  chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue
                                                                         clusterID:DecodableType::GetClusterId()
                                                                         commandID:DecodableType::GetCommandId()
                                                                             error:error];
  if (buffer.IsNull()) {
    return nil;
  }

  chip::TLV::TLVReader reader;
  reader.Init(buffer->Start(), buffer->DataLength());

  CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag());
  if (err == CHIP_NO_ERROR) {
    DecodableType decodedStruct;
    err = chip::app::DataModel::Decode(reader, decodedStruct);
    if (err == CHIP_NO_ERROR) {
      err = [self _setFieldsFromDecodableStruct:decodedStruct];
      if (err == CHIP_NO_ERROR) {
        return self;
      }
    }
  }

  NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()];
  MTR_LOG_ERROR("%s", errorStr.UTF8String);
  if (error != nil) {
    NSDictionary * userInfo = @ { NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) };
    *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo];
  }
  return nil;
}
{{/if}}

@end
{{/if}}
{{/inline}}
{{#*inline "oldNameImpl"}}

@implementation MTR{{cluster}}Cluster{{command}}Params
@end
{{/inline}}
{{#if (isSupported (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
{{> completeImpl cluster=(asUpperCamelCase parent.name preserveAcronyms=true)
                 command=(asUpperCamelCase name preserveAcronyms=true)
                 includeRenamedProperties=false}}
{{#if (isStrEqual source "server")}}

@implementation MTR{{asUpperCamelCase parent.name preserveAcronyms=true}}Cluster{{asUpperCamelCase name preserveAcronyms=true}}Params (InternalMethods)

- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::{{asUpperCamelCase parent.name}}::Commands::{{asUpperCamelCase name}}::DecodableType &)decodableStruct
{
  {{#zcl_command_arguments}}
  {
    {{>decode_value target=(concat "self." (asStructPropertyName label)) source=(concat "decodableStruct." (asLowerCamelCase label)) cluster=parent.parent.name errorCode="return err;" depth=0}}
  }
  {{/zcl_command_arguments}}
  return CHIP_NO_ERROR;
}
@end
{{/if}}
{{#if (or (not (isStrEqual (asUpperCamelCase parent.name preserveAcronyms=true) (compatClusterNameRemapping parent.name)))
          (not (isStrEqual (asUpperCamelCase name preserveAcronyms=true) (compatCommandNameRemapping parent.name name))))}}
{{> oldNameImpl cluster=(compatClusterNameRemapping parent.name)
                command=(compatCommandNameRemapping parent.name name)}}
{{/if}}
{{#if (hasRenamedFields (asUpperCamelCase parent.name preserveAcronyms=true) command=(asUpperCamelCase name preserveAcronyms=true))}}
{{#*inline "deprecatedImpl"}}

@implementation MTR{{cluster}}Cluster{{command}}Params (Deprecated)
{{#zcl_command_arguments}}
{{#if (hasOldName ../cluster command=../command commandField=(asStructPropertyName label))}}

{{> renamed_struct_field_impl cluster=parent.parent.name type=type newName=label oldName=(oldName ../cluster command=../command commandField=(asStructPropertyName label))}}
{{/if}}
{{/zcl_command_arguments}}
@end
{{/inline}}
{{> deprecatedImpl cluster=(asUpperCamelCase parent.name preserveAcronyms=true)
                   command=(asUpperCamelCase name preserveAcronyms=true)}}
{{/if}}
{{else}}
{{> completeImpl cluster=(compatClusterNameRemapping parent.name)
                 command=(compatCommandNameRemapping parent.name name)
                 includeRenamedProperties=true}}
{{/if}}
{{/zcl_commands}}
{{/zcl_clusters}}

NS_ASSUME_NONNULL_END
