#include <jni.h>
#include "react-native-xxhash.h"
#include "jsi/jsi.h"
#include <android/log.h>
#include <fbjni/fbjni.h>
#include <fbjni/detail/Registration.h>
#include <typeinfo>

//XXHashBridge


using namespace facebook;

struct XXHashBridge : jni::JavaClass<XXHashBridge> {
public:
    static constexpr auto kJavaDescriptor = "Lcom/xxhash/XxhashModule;";

    static void registerNatives() {
        javaClassStatic()->registerNatives({
                                                   makeNativeMethod("nativeInstall", XXHashBridge::nativeInstall),
                                                   makeNativeMethod("nativeHash128", XXHashBridge::nativeHash128),
                                                   makeNativeMethod("nativeHash64", XXHashBridge::nativeHash64)
                                           });
    }
private:
    static void nativeInstall(
            jni::alias_ref<jni::JObject> thiz,
            jlong jsiRuntimePointer
    ) {

        // Реализация
        auto jsiRuntime = reinterpret_cast<jsi::Runtime*>(jsiRuntimePointer);
        // Установите JSI
        xxhash::install(jsiRuntime);
    }

    // Synchronous bridge hashers — the JS guard's fallback for when the JSI
    // globals (__xxhash128/__xxhash64) aren't installed yet (bridgeless installs
    // them lazily). Same xxhash::make_hash_* as the JSI path -> bit-identical.
    static jni::local_ref<jni::JString> nativeHash128(
            jni::alias_ref<jni::JObject> thiz,
            jni::alias_ref<jni::JString> input
    ) {
        std::string str = input ? input->toStdString() : std::string();
        char result[33] = {0};
        xxhash::make_hash_128(str, result);
        return jni::make_jstring(result);
    }

    static jni::local_ref<jni::JString> nativeHash64(
            jni::alias_ref<jni::JObject> thiz,
            jni::alias_ref<jni::JString> input
    ) {
        std::string str = input ? input->toStdString() : std::string();
        char result[17] = {0};
        xxhash::make_hash_64(str, result);
        return jni::make_jstring(result);
    }
};

JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) {
    return jni::initialize(vm, [] { XXHashBridge::registerNatives(); });
}
