/**
 * 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.
 */

// This file is autogenerated by
//     weex/weex_core/Source/android/jniprebuild/jni_generator.py
// For
//     org/apache/weex/bridge/RequestHandler

#ifndef com_taobao_weex_bridge_RequestHandler_JNI
#define com_taobao_weex_bridge_RequestHandler_JNI

#include <jni.h>
#include "base/android/jni/android_jni.h"
//#include "base/android/jni_int_wrapper.h"

// Step 1: forward declarations.
namespace {
const char kRequestHandlerClassPath[] = "org/apache/weex/bridge/RequestHandler";
// Leaking this jclass as we cannot use LazyInstance from some threads.
jclass g_RequestHandler_clazz = NULL;
#define RequestHandler_clazz(env) g_RequestHandler_clazz

}  // namespace

static void InvokeOnSuccess(JNIEnv* env, jobject jcaller,
    jlong callback,
    jstring script,
    jstring bundleType);

static void InvokeOnFailed(JNIEnv* env, jobject jcaller,
    jlong callback);

// Step 2: method stubs.

static intptr_t g_RequestHandler_create = 0;
static base::android::ScopedLocalJavaRef<jobject>
    Java_RequestHandler_create(JNIEnv* env) {
  /* Must call RegisterNativesImpl()  */
  //CHECK_CLAZZ(env, RequestHandler_clazz(env),
  //    RequestHandler_clazz(env), NULL);
  jmethodID method_id =
      base::android::GetMethod(
      env, RequestHandler_clazz(env),
      base::android::STATIC_METHOD,
      "create",

"("
")"
"Lorg/apache/weex/bridge/RequestHandler;",
      &g_RequestHandler_create);

  jobject ret =
      env->CallStaticObjectMethod(RequestHandler_clazz(env),
          method_id);
  base::android::CheckException(env);
  return base::android::ScopedLocalJavaRef<jobject>(env, ret);
}

static intptr_t g_RequestHandler_send = 0;
static void Java_RequestHandler_send(JNIEnv* env, jobject obj, jstring
    instanceId,
    jstring url,
    jlong nativeCallback) {
  /* Must call RegisterNativesImpl()  */
  //CHECK_CLAZZ(env, obj,
  //    RequestHandler_clazz(env));
  jmethodID method_id =
      base::android::GetMethod(
      env, RequestHandler_clazz(env),
      base::android::INSTANCE_METHOD,
      "send",

"("
"Ljava/lang/String;"
"Ljava/lang/String;"
"J"
")"
"V",
      &g_RequestHandler_send);

     env->CallVoidMethod(obj,
          method_id, instanceId, url, nativeCallback);
  base::android::CheckException(env);

}

static intptr_t g_RequestHandler_getBundleType = 0;
static void Java_RequestHandler_getBundleType (JNIEnv* env, jobject obj,
    jstring instanceId,jstring content,jlong nativeCallback) {
  /* Must call RegisterNativesImpl()  */
  //CHECK_CLAZZ(env, obj,
  //    RequestHandler_clazz(env));
  jmethodID method_id =
      base::android::GetMethod(
          env, RequestHandler_clazz(env),
          base::android::INSTANCE_METHOD,
          "getBundleType",

          "("
          "Ljava/lang/String;"
          "Ljava/lang/String;"
          "J"
          ")"
          "V",
          &g_RequestHandler_getBundleType);

  env->CallVoidMethod(obj,
                      method_id, instanceId, content, nativeCallback);
  base::android::CheckException(env);

}

// Step 3: RegisterNatives.

static const JNINativeMethod kMethodsRequestHandler[] = {
    { "nativeInvokeOnSuccess",
"("
"J"
"Ljava/lang/String;"
"Ljava/lang/String;"
")"
"V", reinterpret_cast<void*>(InvokeOnSuccess) },
    { "nativeInvokeOnFailed",
"("
"J"
")"
"V", reinterpret_cast<void*>(InvokeOnFailed) },
};

static bool RegisterNativesImpl(JNIEnv* env) {

  g_RequestHandler_clazz = reinterpret_cast<jclass>(env->NewGlobalRef(
      base::android::GetClass(env, kRequestHandlerClassPath).Get()));

  const int kMethodsRequestHandlerSize =
      sizeof(kMethodsRequestHandler)/sizeof(kMethodsRequestHandler[0]);

  if (env->RegisterNatives(RequestHandler_clazz(env),
                           kMethodsRequestHandler,
                           kMethodsRequestHandlerSize) < 0) {
    //jni_generator::HandleRegistrationError(
    //    env, RequestHandler_clazz(env), __FILE__);
    return false;
  }

  return true;
}

#endif  // com_taobao_weex_bridge_RequestHandler_JNI
