/*
 * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#include "jdk_internal_foreign_abi_fallback_LibFallback.h"

#include <ffi.h>

#include <errno.h>
#include <stdalign.h>
#include <stdint.h>
#include <stdlib.h>
#include <wchar.h>
#ifdef _WIN64
#include <Windows.h>
#include <Winsock2.h>
#endif

#include "jlong.h"

static JavaVM* VM;
static jclass LibFallback_class;
static jmethodID LibFallback_doUpcall_ID;
static const char* LibFallback_doUpcall_sig = "(JJLjava/lang/invoke/MethodHandle;)V";

#define CHECK_NULL(expr) \
  if (expr == NULL) { \
    return JNI_FALSE; \
  }

JNIEXPORT jboolean JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_init(JNIEnv* env, jclass cls) {
  jint result = (*env)->GetJavaVM(env, &VM);
  if (result != 0) {
    return JNI_FALSE;
  }

  jclass LibFallback_class_local = (*env)->FindClass(env, "jdk/internal/foreign/abi/fallback/LibFallback");
  CHECK_NULL(LibFallback_class_local)

  LibFallback_class = (*env)->NewGlobalRef(env, LibFallback_class_local);
  CHECK_NULL(LibFallback_class)

  LibFallback_doUpcall_ID = (*env)->GetStaticMethodID(env,
    LibFallback_class, "doUpcall", LibFallback_doUpcall_sig);
  CHECK_NULL(LibFallback_doUpcall_ID)

  return JNI_TRUE;
}

JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_sizeofCif(JNIEnv* env, jclass cls) {
  return sizeof(ffi_cif);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1prep_1cif(JNIEnv* env, jclass cls, jlong cif, jint abi, jint nargs, jlong rtype, jlong atypes) {
  return ffi_prep_cif(jlong_to_ptr(cif), (ffi_abi) abi, (unsigned int) nargs, jlong_to_ptr(rtype), jlong_to_ptr(atypes));
}
JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1prep_1cif_1var(JNIEnv* env, jclass cls, jlong cif, jint abi, jint nfixedargs, jint ntotalargs, jlong rtype, jlong atypes) {
  return ffi_prep_cif_var(jlong_to_ptr(cif), (ffi_abi) abi, (unsigned int) nfixedargs, (unsigned int) ntotalargs, jlong_to_ptr(rtype), jlong_to_ptr(atypes));
}
JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1get_1struct_1offsets(JNIEnv* env, jclass cls, jint abi, jlong type, jlong offsets) {
  return ffi_get_struct_offsets((ffi_abi) abi, jlong_to_ptr(type), jlong_to_ptr(offsets));
}

static void do_capture_state(int32_t* value_ptr, int captured_state_mask) {
    // keep in synch with jdk.internal.foreign.abi.CapturableState
  enum PreservableValues {
    NONE = 0,
    GET_LAST_ERROR = 1,
    WSA_GET_LAST_ERROR = 1 << 1,
    ERRNO = 1 << 2
  };
#ifdef _WIN64
  if (captured_state_mask & GET_LAST_ERROR) {
    *value_ptr = GetLastError();
  }
  value_ptr++;
  if (captured_state_mask & WSA_GET_LAST_ERROR) {
    *value_ptr = WSAGetLastError();
  }
  value_ptr++;
#endif
  if (captured_state_mask & ERRNO) {
    *value_ptr = errno;
  }
}

JNIEXPORT void JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_doDowncall(JNIEnv* env, jclass cls, jlong cif, jlong fn, jlong rvalue,
                                                              jlong avalues,
                                                              jarray capture_state_heap_base, jlong captured_state_offset,
                                                              jint captured_state_mask,
                                                              jarray heapBases, jint numArgs) {
  void** carrays;
  int capture_state_hb_offset = numArgs;
  int32_t* captured_state_addr = jlong_to_ptr(captured_state_offset);
  if (heapBases != NULL) {
    void** aptrs = jlong_to_ptr(avalues);
    carrays = malloc(sizeof(void*) * (numArgs + 1));
    for (int i = 0; i < numArgs; i++) {
      jarray hb = (jarray) (*env)->GetObjectArrayElement(env, heapBases, i);
      if (hb != NULL) {
        // *(aptrs[i]) is the offset into the segment (from MS::address)
        // we add the base address of the array to it here
        jboolean isCopy;
        jbyte* arrayPtr = (*env)->GetPrimitiveArrayCritical(env, hb, &isCopy);
        carrays[i] = arrayPtr;
        int offset = *((int*)aptrs[i]);
        *((void**)aptrs[i]) = arrayPtr + offset;
      }
    }
    if (capture_state_heap_base != NULL) {
        jboolean isCopy;
        jbyte* arrayPtr = (*env)->GetPrimitiveArrayCritical(env, capture_state_heap_base, &isCopy);
        carrays[capture_state_hb_offset] = arrayPtr;
        captured_state_addr = (int32_t*) (arrayPtr + captured_state_offset);
    }
  }

  ffi_call(jlong_to_ptr(cif), jlong_to_ptr(fn), jlong_to_ptr(rvalue), jlong_to_ptr(avalues));

  if (captured_state_mask != 0) {
    do_capture_state(captured_state_addr, captured_state_mask);
  }

  if (heapBases != NULL) {
    for (int i = 0; i < numArgs; i++) {
      jarray hb = (jarray) (*env)->GetObjectArrayElement(env, heapBases, i);
      if (hb != NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, hb, carrays[i], JNI_COMMIT);
      }
    }
    if (capture_state_heap_base != NULL) {
        (*env)->ReleasePrimitiveArrayCritical(env, capture_state_heap_base, carrays[capture_state_hb_offset], JNI_COMMIT);
    }
    free(carrays);
  }
}

static void do_upcall(ffi_cif* cif, void* ret, void** args, void* user_data) {
  // attach thread
  JNIEnv* env;
  (*VM)->AttachCurrentThreadAsDaemon(VM, (void**) &env, NULL);

  // call into doUpcall in LibFallback
  jobject upcall_data = (jobject) user_data;
  (*env)->CallStaticVoidMethod(env, LibFallback_class, LibFallback_doUpcall_ID,
    ptr_to_jlong(ret), ptr_to_jlong(args), upcall_data);

  // always detach for now
  (*VM)->DetachCurrentThread(VM);
}

static void free_closure(JNIEnv* env, void* closure, jobject upcall_data) {
  ffi_closure_free(closure);
  (*env)->DeleteGlobalRef(env, upcall_data);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_createClosure(JNIEnv* env, jclass cls, jlong cif, jobject upcall_data, jlongArray jptrs) {
  void* code;
  void* closure = ffi_closure_alloc(sizeof(ffi_closure), &code);

  jobject global_upcall_data = (*env)->NewGlobalRef(env, upcall_data);

  ffi_status status = ffi_prep_closure_loc(closure, jlong_to_ptr(cif), &do_upcall, (void*) global_upcall_data, code);

  if (status != FFI_OK) {
    free_closure(env,closure, global_upcall_data);
    return status;
  }

  jlong* ptrs = (*env)->GetLongArrayElements(env, jptrs, NULL);
  ptrs[0] = ptr_to_jlong(closure);
  ptrs[1] = ptr_to_jlong(code);
  ptrs[2] = ptr_to_jlong(global_upcall_data);
  (*env)->ReleaseLongArrayElements(env, jptrs, ptrs, JNI_COMMIT);

  return status;
}

JNIEXPORT void JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_freeClosure(JNIEnv* env, jclass cls, jlong closure, jlong upcall_data) {
  free_closure(env, jlong_to_ptr(closure), jlong_to_ptr(upcall_data));
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1default_1abi(JNIEnv* env, jclass cls) {
  return (jint) FFI_DEFAULT_ABI;
}

JNIEXPORT jshort JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1struct(JNIEnv* env, jclass cls) {
  return (jshort) FFI_TYPE_STRUCT;
}

JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1void(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_void);
}

JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1uint8(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_uint8);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1sint8(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_sint8);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1uint16(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_uint16);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1sint16(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_sint16);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1uint32(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_uint32);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1sint32(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_sint32);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1uint64(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_uint64);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1sint64(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_sint64);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1float(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_float);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1double(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_double);
}
JNIEXPORT jlong JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1type_1pointer(JNIEnv* env, jclass cls) {
  return ptr_to_jlong(&ffi_type_pointer);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1sizeof_1short(JNIEnv* env, jclass cls) {
  return sizeof(short);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1sizeof_1int(JNIEnv* env, jclass cls) {
  return sizeof(int);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1sizeof_1long(JNIEnv* env, jclass cls) {
  return sizeof(long);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_ffi_1sizeof_1wchar(JNIEnv* env, jclass cls) {
  return sizeof(wchar_t);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_alignof_1long_1long(JNIEnv* env, jclass cls) {
  return alignof(long long);
}

JNIEXPORT jint JNICALL
Java_jdk_internal_foreign_abi_fallback_LibFallback_alignof_1double(JNIEnv* env, jclass cls) {
  return alignof(double);
}
