// Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
//
// This file implements the "bridge" between Java and C++ for
// rocksdb::Slice.

#include <stdio.h>
#include <stdlib.h>
#include <jni.h>
#include <string>

#include "include/org_rocksdb_AbstractSlice.h"
#include "include/org_rocksdb_Slice.h"
#include "include/org_rocksdb_DirectSlice.h"
#include "rocksdb/slice.h"
#include "rocksjni/portal.h"

// <editor-fold desc="org.rocksdb.AbstractSlice>

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    createNewSliceFromString
 * Signature: (Ljava/lang/String;)J
 */
jlong Java_org_rocksdb_AbstractSlice_createNewSliceFromString(
    JNIEnv * env, jclass jcls, jstring jstr) {
  const auto* str = env->GetStringUTFChars(jstr, nullptr);
  if(str == nullptr) {
    // exception thrown: OutOfMemoryError
    return 0;
  }

  const size_t len = strlen(str);

  // NOTE: buf will be deleted in the
  // Java_org_rocksdb_Slice_disposeInternalBuf or
  // or Java_org_rocksdb_DirectSlice_disposeInternalBuf methods
  char* buf = new char[len + 1];
  memcpy(buf, str, len);
  buf[len] = 0;
  env->ReleaseStringUTFChars(jstr, str);

  const auto* slice = new rocksdb::Slice(buf);
  return reinterpret_cast<jlong>(slice);
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    size0
 * Signature: (J)I
 */
jint Java_org_rocksdb_AbstractSlice_size0(
    JNIEnv* env, jobject jobj, jlong handle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  return static_cast<jint>(slice->size());
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    empty0
 * Signature: (J)Z
 */
jboolean Java_org_rocksdb_AbstractSlice_empty0(
    JNIEnv* env, jobject jobj, jlong handle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  return slice->empty();
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    toString0
 * Signature: (JZ)Ljava/lang/String;
 */
jstring Java_org_rocksdb_AbstractSlice_toString0(
    JNIEnv* env, jobject jobj, jlong handle, jboolean hex) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const std::string s = slice->ToString(hex);
  return env->NewStringUTF(s.c_str());
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    compare0
 * Signature: (JJ)I;
 */
jint Java_org_rocksdb_AbstractSlice_compare0(
    JNIEnv* env, jobject jobj, jlong handle, jlong otherHandle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const auto* otherSlice =
    reinterpret_cast<rocksdb::Slice*>(otherHandle);
  return slice->compare(*otherSlice);
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    startsWith0
 * Signature: (JJ)Z;
 */
jboolean Java_org_rocksdb_AbstractSlice_startsWith0(
    JNIEnv* env, jobject jobj, jlong handle, jlong otherHandle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const auto* otherSlice =
    reinterpret_cast<rocksdb::Slice*>(otherHandle);
  return slice->starts_with(*otherSlice);
}

/*
 * Class:     org_rocksdb_AbstractSlice
 * Method:    disposeInternal
 * Signature: (J)V
 */
void Java_org_rocksdb_AbstractSlice_disposeInternal(
    JNIEnv* env, jobject jobj, jlong handle) {
  delete reinterpret_cast<rocksdb::Slice*>(handle);
}

// </editor-fold>

// <editor-fold desc="org.rocksdb.Slice>

/*
 * Class:     org_rocksdb_Slice
 * Method:    createNewSlice0
 * Signature: ([BI)J
 */
jlong Java_org_rocksdb_Slice_createNewSlice0(
    JNIEnv * env, jclass jcls, jbyteArray data, jint offset) {
  const jsize dataSize = env->GetArrayLength(data);
  const int len = dataSize - offset;

  // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf method
  jbyte* buf = new jbyte[len];
  env->GetByteArrayRegion(data, offset, len, buf);
  if(env->ExceptionCheck()) {
    // exception thrown: ArrayIndexOutOfBoundsException
    return 0;
  }

  const auto* slice = new rocksdb::Slice((const char*)buf, len);
  return reinterpret_cast<jlong>(slice);
}

/*
 * Class:     org_rocksdb_Slice
 * Method:    createNewSlice1
 * Signature: ([B)J
 */
jlong Java_org_rocksdb_Slice_createNewSlice1(
    JNIEnv * env, jclass jcls, jbyteArray data) {
  jbyte* ptrData = env->GetByteArrayElements(data, nullptr);
  if(ptrData == nullptr) {
    // exception thrown: OutOfMemoryError
    return 0;
  }
  const int len = env->GetArrayLength(data) + 1;

  // NOTE: buf will be deleted in the Java_org_rocksdb_Slice_disposeInternalBuf method
  char* buf = new char[len];
  memcpy(buf, ptrData, len - 1);
  buf[len-1] = '\0';

  const auto* slice =
      new rocksdb::Slice(buf, len - 1);

  env->ReleaseByteArrayElements(data, ptrData, JNI_ABORT);

  return reinterpret_cast<jlong>(slice);
}

/*
 * Class:     org_rocksdb_Slice
 * Method:    data0
 * Signature: (J)[B
 */
jbyteArray Java_org_rocksdb_Slice_data0(
    JNIEnv* env, jobject jobj, jlong handle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const jsize len = static_cast<jsize>(slice->size());
  const jbyteArray data = env->NewByteArray(len);
  if(data == nullptr) {
    // exception thrown: OutOfMemoryError
    return nullptr;
  }
  
  env->SetByteArrayRegion(data, 0, len,
    const_cast<jbyte*>(reinterpret_cast<const jbyte*>(slice->data())));
  if(env->ExceptionCheck()) {
    // exception thrown: ArrayIndexOutOfBoundsException
    env->DeleteLocalRef(data);
    return nullptr;
  }

  return data;
}

/*
 * Class:     org_rocksdb_Slice
 * Method:    clear0
 * Signature: (JZJ)V
 */
void Java_org_rocksdb_Slice_clear0(
    JNIEnv * env, jobject jobj, jlong handle, jboolean shouldRelease,
    jlong internalBufferOffset) {
  auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  if(shouldRelease == JNI_TRUE) {
    const char* buf = slice->data_ - internalBufferOffset;
    delete [] buf;
  }
  slice->clear();
}

/*
 * Class:     org_rocksdb_Slice
 * Method:    removePrefix0
 * Signature: (JI)V
 */
void Java_org_rocksdb_Slice_removePrefix0(
    JNIEnv * env, jobject jobj, jlong handle, jint length) {
  auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  slice->remove_prefix(length);
}

/*
 * Class:     org_rocksdb_Slice
 * Method:    disposeInternalBuf
 * Signature: (JJ)V
 */
void Java_org_rocksdb_Slice_disposeInternalBuf(
    JNIEnv * env, jobject jobj, jlong handle, jlong internalBufferOffset) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const char* buf = slice->data_ - internalBufferOffset;
  delete [] buf;
}

// </editor-fold>

// <editor-fold desc="org.rocksdb.DirectSlice>

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    createNewDirectSlice0
 * Signature: (Ljava/nio/ByteBuffer;I)J
 */
jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice0(
    JNIEnv* env, jclass jcls, jobject data, jint length) {
  assert(data != nullptr);
  void* data_addr = env->GetDirectBufferAddress(data);
  if(data_addr == nullptr) {
    // error: memory region is undefined, given object is not a direct
    // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
    rocksdb::IllegalArgumentExceptionJni::ThrowNew(env,
        rocksdb::Status::InvalidArgument(
            "Could not access DirectBuffer"));
    return 0;
  }

  const auto* ptrData =
     reinterpret_cast<char*>(data_addr);
  const auto* slice = new rocksdb::Slice(ptrData, length);
  return reinterpret_cast<jlong>(slice);
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    createNewDirectSlice1
 * Signature: (Ljava/nio/ByteBuffer;)J
 */
jlong Java_org_rocksdb_DirectSlice_createNewDirectSlice1(
    JNIEnv* env, jclass jcls, jobject data) {
  void* data_addr = env->GetDirectBufferAddress(data);
  if(data_addr == nullptr) {
    // error: memory region is undefined, given object is not a direct
    // java.nio.Buffer, or JNI access to direct buffers is not supported by JVM
    rocksdb::IllegalArgumentExceptionJni::ThrowNew(env,
        rocksdb::Status::InvalidArgument(
            "Could not access DirectBuffer"));
    return 0;
  }

  const auto* ptrData = reinterpret_cast<char*>(data_addr);
  const auto* slice = new rocksdb::Slice(ptrData);
  return reinterpret_cast<jlong>(slice);
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    data0
 * Signature: (J)Ljava/lang/Object;
 */
jobject Java_org_rocksdb_DirectSlice_data0(
    JNIEnv* env, jobject jobj, jlong handle) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  return env->NewDirectByteBuffer(const_cast<char*>(slice->data()),
    slice->size());
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    get0
 * Signature: (JI)B
 */
jbyte Java_org_rocksdb_DirectSlice_get0(
    JNIEnv* env, jobject jobj, jlong handle, jint offset) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  return (*slice)[offset];
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    clear0
 * Signature: (JZJ)V
 */
void Java_org_rocksdb_DirectSlice_clear0(
    JNIEnv* env, jobject jobj, jlong handle,
    jboolean shouldRelease, jlong internalBufferOffset) {
  auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  if(shouldRelease == JNI_TRUE) {
    const char* buf = slice->data_ - internalBufferOffset;
    delete [] buf;
  }
  slice->clear();
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    removePrefix0
 * Signature: (JI)V
 */
void Java_org_rocksdb_DirectSlice_removePrefix0(
    JNIEnv* env, jobject jobj, jlong handle, jint length) {
  auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  slice->remove_prefix(length);
}

/*
 * Class:     org_rocksdb_DirectSlice
 * Method:    disposeInternalBuf
 * Signature: (JJ)V
 */
void Java_org_rocksdb_DirectSlice_disposeInternalBuf(
    JNIEnv* env, jobject jobj, jlong handle, jlong internalBufferOffset) {
  const auto* slice = reinterpret_cast<rocksdb::Slice*>(handle);
  const char* buf = slice->data_ - internalBufferOffset;
  delete [] buf;
}

// </editor-fold>
