{%- macro encode_optional(target, source, depth, encodable) -%}
  {
    jobject optionalValue_{{depth}} = nullptr;
    chip::JniReferences::GetInstance().GetOptionalValue({{source}}, optionalValue_{{depth}});
    if (optionalValue_{{depth}}) {
      auto & definedValue_{{depth}} = {{target}}.Emplace();
      {{ encode_value(
          "definedValue_{}".format(depth),
          "optionalValue_{}".format(depth),
          depth+1,
          encodable.without_optional()
      )}}
    }
  }
{%- endmacro %}

{%- macro encode_nullable(target, source, depth, encodable) -%}
  if ({{source}} == nullptr) {
    {{target}}.SetNull();
  } else {
    auto & nonNullValue_{{depth}} = {{target}}.SetNonNull();
    {{encode_value("nonNullValue_{}".format(depth), source, depth+1, encodable.without_nullable())}}
  }
{%- endmacro %}

{%- macro encode_list(target, source, depth, encodable) -%}
  {
    using ListType_{{depth}} = std::remove_reference_t<decltype({{target}})>;
    using ListMemberType_{{depth}} = ListMemberTypeGetter<ListType_{{depth}}>::Type;
    jint {{source}}Size;
    chip::JniReferences::GetInstance().GetListSize({{source}}, {{source}}Size);
    if ({{source}}Size != 0) {
      auto * listHolder_{{depth}} = new ListHolder<ListMemberType_{{depth}}>({{source}}Size);
      listFreer.add(listHolder_{{depth}});

      for (jint i_{{depth}} = 0; i_{{depth}} < {{source}}Size; ++i_{{depth}}) {
        jobject element_{{depth}};
        chip::JniReferences::GetInstance().GetListItem({{source}}, i_{{depth}}, element_{{depth}});
        {{encode_value(
           "listHolder_{}->mList[static_cast<uint32_t>(i_{})]".format(depth, depth),
           "element_{}".format(depth),
           depth+1, encodable.without_list()
        )}}
      }
      {{target}} = ListType_{{depth}}(listHolder_{{depth}}->mList, {{source}}Size);
    } else {
      {{target}} = ListType_{{depth}}();
    }
  }
{%- endmacro %}

{%- macro encode_value(target, source, depth, encodable) -%}
    {%- if encodable.is_optional -%}
        {{encode_optional(target, source, depth, encodable)}}
    {%- elif encodable.is_nullable -%}
        {{encode_nullable(target, source, depth, encodable)}}
    {%- elif encodable.is_list -%}
        {{encode_list(target, source, depth, encodable)}}
    {%- elif encodable.is_octet_string -%}
        cleanupByteArrays.push_back(chip::Platform::MakeUnique<chip::JniByteArray>(env, static_cast<jbyteArray>({{source}})));
        {{target}} = cleanupByteArrays.back()->byteSpan();
    {%- elif encodable.is_char_string -%}
        cleanupStrings.push_back(chip::Platform::MakeUnique<chip::JniUtfString>(env, static_cast<jstring>({{source}})));
        {{target}} = cleanupStrings.back()->charSpan();
    {%- elif encodable.is_struct -%}
        {% set struct = encodable.get_underlying_struct()  -%}
        {%   for field in struct.fields %}
          {% set fieldEncodable = field | asEncodable(encodable.context) -%}
          jobject {{source}}_{{field.name}}Item_{{depth}};
          chip::JniReferences::GetInstance().GetObjectField({{source}}, "{{field.name}}", "{{fieldEncodable.boxed_java_signature}}", {{source}}_{{field.name}}Item_{{depth}});
          {{ encode_value(
              "{}.{}".format(target, field.name | lowercaseFirst),
              "{}_{}Item_{}".format(source, field.name, depth),
              depth + 1,
              fieldEncodable
          )}}
        {%-   endfor -%}
    {%- elif encodable.is_enum -%}
        {{target}} = static_cast<std::remove_reference_t<decltype({{target}})>>(chip::JniReferences::GetInstance().IntegerToPrimitive({{source}}));
    {%- elif encodable.is_untyped_bitmap -%}
        {{target}} = static_cast<std::remove_reference_t<decltype({{target}})>>(chip::JniReferences::GetInstance().{{encodable.boxed_java_type}}ToPrimitive({{source}}));
    {%- elif encodable.is_bitmap -%}
        {{target}}.SetRaw(static_cast<std::remove_reference_t<decltype({{target}})>::IntegerType>(chip::JniReferences::GetInstance().{{encodable.boxed_java_type}}ToPrimitive({{source}})));
    {% else -%}
        {{target}} = static_cast<std::remove_reference_t<decltype({{target}})>>(chip::JniReferences::GetInstance().{{encodable.boxed_java_type}}ToPrimitive({{source}}));
    {% endif -%}
{% endmacro -%}

#include <jni/CHIPCallbackTypes.h>
#include <jni/CHIPReadCallbacks.h>
#include <controller/CHIPCluster.h>
#include <controller/java/zap-generated/CHIPInvokeCallbacks.h>

#include <app-common/zap-generated/cluster-objects.h>
#include <zap-generated/CHIPClientCallbacks.h>

#include <controller/java/AndroidCallbacks.h>
#include <controller/java/AndroidClusterExceptions.h>
#include <controller/java/CHIPDefaultCallbacks.h>
#include <jni.h>
#include <lib/support/CHIPListUtils.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/Span.h>
#include <platform/PlatformManager.h>
#include <vector>

#include <jni/CHIPCallbackTypes.h>

#define JNI_METHOD(RETURN, CLASS_NAME, METHOD_NAME)                                                                                \
    extern "C" JNIEXPORT RETURN JNICALL Java_chip_devicecontroller_ChipClusters_00024##CLASS_NAME##_##METHOD_NAME

using namespace chip;
using chip::Controller::ClusterBase;

JNI_METHOD(jlong, {{cluster.name | capitalcase}}Cluster, initWithDevice)(JNIEnv * env, jobject self, jlong devicePtr, jint endpointId)
{
    chip::DeviceLayer::StackLock lock;
    DeviceProxy * device = reinterpret_cast<DeviceProxy *>(devicePtr);
    ClusterBase * cppCluster = new ClusterBase(*device->GetExchangeManager(), device->GetSecureSession().Value(), endpointId);
    return reinterpret_cast<jlong>(cppCluster);
}

{% for command in cluster.commands -%}

JNI_METHOD(void, {{cluster.name | capitalcase}}Cluster, 
  {{command.name | lowercaseFirst}})(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback,
  {%- if command.input_param -%}
  {%-    for field in (cluster.structs | named(command.input_param)).fields -%}
    {{ field | toBoxedJavaType }} {{field.name}},
  {%-    endfor  -%}
  {%- endif -%}
    jobject timedInvokeTimeoutMs)
{
    chip::DeviceLayer::StackLock lock;
    CHIP_ERROR err = CHIP_NO_ERROR;
    ClusterBase * cppCluster;

    ListFreer listFreer;
    chip::app::Clusters::{{cluster.name | capitalcase}}::Commands::{{command.name | capitalcase}}::Type request;

    std::vector<Platform::UniquePtr<JniByteArray>> cleanupByteArrays;
    std::vector<Platform::UniquePtr<JniUtfString>> cleanupStrings;
  {%- if command.input_param -%}
  {%-   for field in (cluster.structs | named(command.input_param)).fields -%}
    {{ encode_value(
        "request." + (field.name | lowercaseFirst),
        (field.name | lowercaseFirst),
        0,
        field | asEncodable(typeLookup)
    )}}
  {%-   endfor -%}
  {% endif %}

  {% set callbackName = command | commandCallbackName(cluster) %}
    std::unique_ptr<CHIP{{callbackName}}Callback, void (*)(CHIP{{callbackName}}Callback *)> onSuccess(
        Platform::New<CHIP{{callbackName}}Callback>(callback), Platform::Delete<CHIP{{callbackName}}Callback>);
    std::unique_ptr<CHIPDefaultFailureCallback, void (*)(CHIPDefaultFailureCallback *)> onFailure(Platform::New<CHIPDefaultFailureCallback>(callback), Platform::Delete<CHIPDefaultFailureCallback>);
    VerifyOrReturn(onSuccess.get() != nullptr, AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native callback", CHIP_ERROR_NO_MEMORY));
    VerifyOrReturn(onFailure.get() != nullptr, AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native callback", CHIP_ERROR_NO_MEMORY));

    cppCluster = reinterpret_cast<ClusterBase *>(clusterPtr);
    VerifyOrReturn(cppCluster != nullptr, AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error getting native cluster", CHIP_ERROR_INCORRECT_STATE));

    auto successFn = chip::Callback::Callback<CHIP{{callbackName}}CallbackType>::FromCancelable(onSuccess->Cancel());
    auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());

  {% if command.is_timed_invoke -%}
    err = cppCluster->InvokeCommand(request, onSuccess->mContext, successFn->mCall, failureFn->mCall, chip::JniReferences::GetInstance().IntegerToPrimitive(timedInvokeTimeoutMs));
  {%- else -%}
    if (timedInvokeTimeoutMs == nullptr) {
        err = cppCluster->InvokeCommand(request, onSuccess->mContext, successFn->mCall, failureFn->mCall);
    } else {
        err = cppCluster->InvokeCommand(request, onSuccess->mContext, successFn->mCall, failureFn->mCall, chip::JniReferences::GetInstance().IntegerToPrimitive(timedInvokeTimeoutMs));
    }
  {%- endif %}
    VerifyOrReturn(err == CHIP_NO_ERROR, AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error invoking command", CHIP_ERROR_INCORRECT_STATE));

    onSuccess.release();
    onFailure.release();
}
{% endfor %}

{%- for attr in cluster.attributes if attr.is_subscribable -%}
{%-   if attr | canGenerateSubscribe(typeLookup) -%}

JNI_METHOD(void, {{cluster.name}}Cluster, subscribe{{attr.definition.name | capitalcase}}Attribute)(JNIEnv * env, jobject self, jlong clusterPtr, jobject callback, jint minInterval, jint maxInterval)
{
    chip::DeviceLayer::StackLock lock;

    {%- set callbackName = attr | callbackName(typeLookup) -%}

    std::unique_ptr<{{callbackName}}, void (*)({{callbackName}} *)> onSuccess(Platform::New<{{callbackName}}>(callback, true), chip::Platform::Delete<{{callbackName}}>);
    VerifyOrReturn(onSuccess.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native success callback", CHIP_ERROR_NO_MEMORY));

    std::unique_ptr<CHIPDefaultFailureCallback, void (*)(CHIPDefaultFailureCallback *)> onFailure(Platform::New<CHIPDefaultFailureCallback>(callback), chip::Platform::Delete<CHIPDefaultFailureCallback>);
    VerifyOrReturn(onFailure.get() != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error creating native failure callback", CHIP_ERROR_NO_MEMORY));

    CHIP_ERROR err = CHIP_NO_ERROR;
    ClusterBase * cppCluster = reinterpret_cast<ClusterBase *>(clusterPtr);
    VerifyOrReturn(cppCluster != nullptr, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Could not get native cluster", CHIP_ERROR_INCORRECT_STATE));

    using TypeInfo = chip::app::Clusters::{{cluster.name}}::Attributes::{{attr.definition.name | capitalcase}}::TypeInfo;
    auto successFn = chip::Callback::Callback<CHIP{{cluster.name}}Cluster{{attr.definition.name | capitalcase}}AttributeCallbackType>::FromCancelable(onSuccess->Cancel());
    auto failureFn = chip::Callback::Callback<CHIPDefaultFailureCallbackType>::FromCancelable(onFailure->Cancel());

    err = cppCluster->SubscribeAttribute<TypeInfo>(onSuccess->mContext, successFn->mCall, failureFn->mCall, static_cast<uint16_t>(minInterval), static_cast<uint16_t>(maxInterval), {{callbackName}}::OnSubscriptionEstablished);
    VerifyOrReturn(err == CHIP_NO_ERROR, chip::AndroidClusterExceptions::GetInstance().ReturnIllegalStateException(env, callback, "Error subscribing to attribute", err));

    onSuccess.release();
    onFailure.release();
}

{%-   endif -%}
{% endfor %}
