/*
 *
 *    Copyright (c) 2023 Project CHIP Authors
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */
#include <jni/CHIPCallbackTypes.h>

#include <controller/java/AndroidCallbacks.h>
#include <jni.h>
#include <lib/support/ErrorStr.h>
#include <lib/support/JniReferences.h>
#include <zap-generated/CHIPClientCallbacks.h>

{% for type in globalTypes -%}
class CHIP{{type.name}}AttributeCallback : public chip::Callback::Callback<{{type.name}}AttributeCallback>
{
public:
    CHIP{{type.name}}AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIP{{type.name}}AttributeCallback();

    static void maybeDestroy(CHIP{{type.name}}AttributeCallback * callback) {
        if (!callback->keepAlive) {
            callback->Cancel();
            chip::Platform::Delete<CHIP{{type.name}}AttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, {{type.cpp_type}} value);
    static void OnSubscriptionEstablished(void * context, chip::SubscriptionId subscriptionId) {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(reinterpret_cast<CHIP{{type.name}}AttributeCallback *>(context)->javaCallbackRef, subscriptionId);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};
{% endfor %}

{% for cluster in clientClusters | sort(attribute='code') %}
  {%  set typeLookup = idl | createLookupContext(cluster) %}
  {%- for attr in cluster.attributes | rejectattr('definition', 'is_using_global_callback', typeLookup) %}
class CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback : public chip::Callback::Callback<CHIP{{cluster.name}}Cluster{{attr.definition.name | capitalcase}}AttributeCallbackType>
{
public:
    CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback(jobject javaCallback, bool keepAlive = false);

    ~CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback();

    static void maybeDestroy(CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback * callback) {
        if (!callback->keepAlive) {
            callback->Cancel();
            chip::Platform::Delete<CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback>(callback);
        }
    }

    static void CallbackFn(void * context, {{attr.definition | decodableJniType(typeLookup)}} {%if attr.definition.is_list%}list{%else%}value{%endif%});
    static void OnSubscriptionEstablished(void * context, chip::SubscriptionId subscriptionId) {
        CHIP_ERROR err = chip::JniReferences::GetInstance().CallSubscriptionEstablished(reinterpret_cast<CHIP{{cluster.name}}{{attr.definition.name | capitalcase}}AttributeCallback *>(context)->javaCallbackRef, subscriptionId);
        VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Error calling onSubscriptionEstablished: %s", ErrorStr(err)));
    };

private:
    jobject javaCallbackRef;
    bool keepAlive;
};

  {% endfor %}
{% endfor %}
