/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "android_jni.h"
#include "base/android/log_utils.h"

namespace {
JavaVM *g_jvm = nullptr;
}

namespace base {
namespace android {

void InitVM(JavaVM *vm) {
  g_jvm = vm;
}

JNIEnv *AttachCurrentThread() {
  JNIEnv *env = nullptr;

  JavaVMAttachArgs args;
  args.version = JNI_VERSION_1_4;
  args.name = "weex_sdk_runtime";
  args.group = nullptr;

  jint ret = g_jvm->AttachCurrentThread(&env, &args);
  if (ret != JNI_OK) {
    LOGE("weex AttachCurrentThread failed");
    env = nullptr;
  }
  return env;
}

void DetachFromVM() {
  if (g_jvm) {
    g_jvm->DetachCurrentThread();
  }
}

ScopedLocalJavaRef<jclass> GetClass(JNIEnv *env, const char *class_name) {
  jclass clazz;
  clazz = env->FindClass(class_name);
  return ScopedLocalJavaRef<jclass>(env, clazz);
}

jclass GetClass(JNIEnv *env, const char *class_name, intptr_t *class_id) {
  if (*class_id) {
    return reinterpret_cast<jclass>(*class_id);
  }
  ScopedGlobalJavaRef<jclass> clazz;
  clazz.Reset(env, GetClass(env, class_name));
  *class_id = reinterpret_cast<intptr_t>(clazz.Release());
  return reinterpret_cast<jclass>(*class_id);
}

jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type,
                    const char *method_name, const char *jni_signature) {
  if (type == STATIC_METHOD) {
    return env->GetStaticMethodID(clazz, method_name, jni_signature);
  } else if (type == INSTANCE_METHOD) {
    return env->GetMethodID(clazz, method_name, jni_signature);
  }
  return 0;
}

jmethodID GetMethod(JNIEnv *env, jclass clazz, MethodType type,
                    const char *method_name, const char *jni_signature, intptr_t *method_id) {
  if (*method_id) {
    return reinterpret_cast<jmethodID>(*method_id);
  }
  *method_id = reinterpret_cast<intptr_t>(GetMethod(env,
                                                    clazz, type, method_name, jni_signature));
  return reinterpret_cast<jmethodID>(*method_id);
}

bool HasException(JNIEnv *env) {
  return env->ExceptionCheck() != JNI_FALSE;
}

bool ClearException(JNIEnv *env) {
  if (!HasException(env))
    return false;
  env->ExceptionDescribe();
  env->ExceptionClear();
  return true;
}

void CheckException(JNIEnv *env) {
  if (!HasException(env))
    return;

  // Exception has been found, might as well tell breakpad about it.
  jthrowable java_throwable = env->ExceptionOccurred();
  if (java_throwable) {
    // Clear the pending exception, since a local reference is now held.
    env->ExceptionDescribe();
    env->ExceptionClear();
  }

  // Now, feel good about it and die.
  // CHECK(false) << "Please include Java exception stack in crash report";
}
}  // namespace android
}  // namespace base
