namespace Core::Java

namespace Java {

// typedefs

typedef jlong JniIntPtr;

// structs

template <typename T>
struct JniCast;

struct JniThreadScope;

// classes

class Jni;
class JniAccessor;

template <typename ArrayType>
class JniArray;

class JniByteArray;
class JniCStringChars;
class JniClass;
class JniClassRegistry;

template <typename T>
class JniField;

class JniFieldBase;
class JniFloatArray;
class JniIntArray;
class JniMethod;
class JniMethodBase;

template <class Ret, class... Args>
class JniMethodTyped;

class JniObject;
class JniObjectArray;
class JniObjectBase;
class JniStaticMethod;

template <class Ret, class... Args>
class JniStaticMethodTyped;

class JniString;
class JniStringArray;
class JniStringChars;

template <class Char>
class JniStringCharsBase;

class LocalRef;
class LocalStringRef;

// global variables

Z I Ljava util Set;
END_DEFINE_JNI_CLASS Ljava lang Object;
Ljava util Iterator;
END_DEFINE_JNI_CLASS Ljava util UUID;
J Ljava lang String;
END_DEFINE_JNI_CLASS Ljava lang Runtime;
hasNext java util List get;

// global functions

DEFINE_JNI_CLASS(Iterator);
Z DEFINE_JNI_METHOD(next, "()Ljava/lang/Object;");
Z I DEFINE_JNI_METHOD(get, "(I)Ljava/lang/Object;");
END_DEFINE_JNI_CLASS DEFINE_JNI_CLASS(MapEntry);
DEFINE_JNI_METHOD(getValue, "()Ljava/lang/Object;");
END_DEFINE_JNI_CLASS DEFINE_JNI_CLASS(UUID);
DEFINE_JNI_METHOD(getLeastSignificantBits, "()J");
J DEFINE_JNI_METHOD(toString, "()Ljava/lang/String;");
END_DEFINE_JNI_CLASS DEFINE_JNI_CLASS(Runtime);
DEFINE_JNI_METHOD(maxMemory, "()J");
J DEFINE_JNI_METHOD(freeMemory, "()J");
V END_DEFINE_JNI_CLASS DEFINE_JNI_CLASS(InetAddress);
DECLARE_JNI_CLASS(Iterator, "java/util/Iterator");
hasNext DECLARE_JNI_METHOD(jobject, next);
hasNext java util List DECLARE_JNI_METHOD(int, size);
hasNext java util List int END_DECLARE_JNI_CLASS(List);
hasNext java util List int java util Map DECLARE_JNI_METHOD(jobject, entrySet);

hasNext java util List int java util Map java util Map$Entry DECLARE_JNI_METHOD(
    jobject,
    getKey
);

hasNext java util List int java util Map java util Map$Entry getValue END_DECLARE_JNI_CLASS(MapEntry);

hasNext java util List int java util Map java util Map$Entry getValue java util Set DECLARE_JNI_METHOD(
    jobject,
    iterator
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID DECLARE_JNI_STATIC_METHOD(
    jobject,
    randomUUID
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits DECLARE_JNI_METHOD(
    int64,
    getMostSignificantBits
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString END_DECLARE_JNI_CLASS(UUID);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File DECLARE_JNI_METHOD(
    jstring,
    getAbsolutePath
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File java lang Runtime DECLARE_JNI_STATIC_METHOD(
    jobject,
    getRuntime
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File java lang Runtime maxMemory DECLARE_JNI_METHOD(
    int64,
    totalMemory
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File java lang Runtime maxMemory freeMemory END_DECLARE_JNI_CLASS(Runtime);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File java lang Runtime maxMemory freeMemory java lang System DECLARE_JNI_STATIC_METHOD(
    void,
    loadLibrary,
    jstring
);

hasNext java util List int java util Map java util Map$Entry getValue java util Set java util UUID getLeastSignificantBits toString java io File java lang Runtime maxMemory freeMemory java lang System java net InetAddress DECLARE_JNI_STATIC_METHOD(
    jobject,
    getByAddress,
    jbyteArray
);

template <typename T>
T jobject_cast(jobject object);

} // namespace Java