%{
#include "mesh_java_interfaces.h"
#include <jni.h>

// Thread-local storage for the current JNIEnv, needed for the call to set the
// Android context
static __thread JNIEnv *current_env = NULL;

// Define a dummy struct inside here so it is visible in the generated code, and
// will be used as part of calling `ditto_sdk_transports_set_android_context
struct EnvMarker {};
%}
typedef int int32_t;

%include "mesh_java_interfaces.h"

%include "cpointer.i"
%include <stdint.i>

%typemap(newfree) char * {
  if ($1 != NULL) {
    ditto_c_string_free($1);
  }
}
%newobject ditto_auth_client_user_id;
%newobject dittoffi_authentication_status_user_id;
%newobject ditto_set_device_name;

%typemap(in, numinputs=0) EnvMarker {
  // This code runs inside the JNI wrapper, where 'jenv' is available.
  current_env = jenv;
}

// Hide EnvMarker from the generated Java interface completely
%typemap(jstype) EnvMarker ""
%typemap(javain) EnvMarker ""
%typemap(javaout) EnvMarker ""
%typemap(javapre) EnvMarker ""

// From Kotlin, we won't see the EnvMarker parameter at all (because of the
// typemap above), but this ensures `current_env` is set before the call, so we
// can pass down the `JNIEnv` pointer.
%inline %{
bool dittoffi_set_android_context(EnvMarker, jobject context) {
    return ditto_sdk_transports_set_android_context(current_env, (void*)context);
}
%}
