/*
 * Copyright (C) 2013 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <assert.h>
#include <stdio.h>
#include <pthread.h>
#include <vector>

#include "jni.h"

#if defined(NDEBUG)
#error test code compiled without NDEBUG
#endif

static JavaVM* jvm = NULL;

extern "C" JNIEXPORT jint JNI_OnLoad(JavaVM *vm, void *) {
  assert(vm != NULL);
  assert(jvm == NULL);
  jvm = vm;
  return JNI_VERSION_1_6;
}

static void* testFindClassOnAttachedNativeThread(void*) {
  assert(jvm != NULL);

  JNIEnv* env = NULL;
  JavaVMAttachArgs args = { JNI_VERSION_1_6, __FUNCTION__, NULL };
  int attach_result = jvm->AttachCurrentThread(&env, &args);
  assert(attach_result == 0);

  jclass clazz = env->FindClass("JniTest");
  assert(clazz != NULL);
  assert(!env->ExceptionCheck());

  jobjectArray array = env->NewObjectArray(0, clazz, NULL);
  assert(array != NULL);
  assert(!env->ExceptionCheck());

  int detach_result = jvm->DetachCurrentThread();
  assert(detach_result == 0);
  return NULL;
}

// http://b/10994325
extern "C" JNIEXPORT void JNICALL Java_JniTest_testFindClassOnAttachedNativeThread(JNIEnv*,
                                                                                   jclass) {
  pthread_t pthread;
  int pthread_create_result = pthread_create(&pthread,
                                             NULL,
                                             testFindClassOnAttachedNativeThread,
                                             NULL);
  assert(pthread_create_result == 0);
  int pthread_join_result = pthread_join(pthread, NULL);
  assert(pthread_join_result == 0);
}

static void* testFindFieldOnAttachedNativeThread(void*) {
  assert(jvm != NULL);

  JNIEnv* env = NULL;
  JavaVMAttachArgs args = { JNI_VERSION_1_6, __FUNCTION__, NULL };
  int attach_result = jvm->AttachCurrentThread(&env, &args);
  assert(attach_result == 0);

  jclass clazz = env->FindClass("JniTest");
  assert(clazz != NULL);
  assert(!env->ExceptionCheck());

  jfieldID field = env->GetStaticFieldID(clazz, "testFindFieldOnAttachedNativeThreadField", "Z");
  assert(field != NULL);
  assert(!env->ExceptionCheck());

  env->SetStaticBooleanField(clazz, field, JNI_TRUE);

  int detach_result = jvm->DetachCurrentThread();
  assert(detach_result == 0);
  return NULL;
}

extern "C" JNIEXPORT void JNICALL Java_JniTest_testFindFieldOnAttachedNativeThreadNative(JNIEnv*,
                                                                                         jclass) {
  pthread_t pthread;
  int pthread_create_result = pthread_create(&pthread,
                                             NULL,
                                             testFindFieldOnAttachedNativeThread,
                                             NULL);
  assert(pthread_create_result == 0);
  int pthread_join_result = pthread_join(pthread, NULL);
  assert(pthread_join_result == 0);
}


// http://b/11243757
extern "C" JNIEXPORT void JNICALL Java_JniTest_testCallStaticVoidMethodOnSubClassNative(JNIEnv* env,
                                                                                        jclass) {
  jclass super_class = env->FindClass("JniTest$testCallStaticVoidMethodOnSubClass_SuperClass");
  assert(super_class != NULL);

  jmethodID execute = env->GetStaticMethodID(super_class, "execute", "()V");
  assert(execute != NULL);

  jclass sub_class = env->FindClass("JniTest$testCallStaticVoidMethodOnSubClass_SubClass");
  assert(sub_class != NULL);

  env->CallStaticVoidMethod(sub_class, execute);
}

extern "C" JNIEXPORT jobject JNICALL Java_JniTest_testGetMirandaMethodNative(JNIEnv* env, jclass) {
  jclass abstract_class = env->FindClass("JniTest$testGetMirandaMethod_MirandaAbstract");
  assert(abstract_class != NULL);
  jmethodID miranda_method = env->GetMethodID(abstract_class, "inInterface", "()Z");
  assert(miranda_method != NULL);
  return env->ToReflectedMethod(abstract_class, miranda_method, JNI_FALSE);
}

// https://code.google.com/p/android/issues/detail?id=63055
extern "C" void JNICALL Java_JniTest_testZeroLengthByteBuffers(JNIEnv* env, jclass) {
  std::vector<uint8_t> buffer(1);
  jobject byte_buffer = env->NewDirectByteBuffer(&buffer[0], 0);
  assert(byte_buffer != NULL);
  assert(!env->ExceptionCheck());

  assert(env->GetDirectBufferAddress(byte_buffer) == &buffer[0]);
  assert(env->GetDirectBufferCapacity(byte_buffer) == 0);
}
