// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "base/android_jni_proxy.h"

#include <jni.h>

#include "base/logging.h"
#include "base/mutex.h"
#include "base/scoped_ptr.h"
#include "net/http_client_common.h"

namespace {

// To invoke Java's method, we need to ensure that the current thread is
// attached to Java VM. This class manages it, and provides a way to access
// JNIEnv instance, which is an interface to call Java's methods.
class ScopedJavaThreadAttacher {
 public:
  explicit ScopedJavaThreadAttacher(JavaVM *jvm) : jvm_(jvm) {
    jni_env_ = GetJNIEnv(jvm_, &attached_);
  }

  ~ScopedJavaThreadAttacher() {
    if (attached_ && jvm_ != NULL) {
      jvm_->DetachCurrentThread();
    }
  }

  // Returned JNIEnv may be invalidated when this instance is destructed.
  JNIEnv *mutable_jni_env() {
    return jni_env_;
  }

 private:
  JavaVM *jvm_;
  JNIEnv *jni_env_;
  bool attached_;

  // Returns JNIEnv instance which attached to the current thread, and
  // stores true into attached, when this thread is newly attached to the
  // Java VM (i.e., the caller has responsibility to detach from the Java VM.
  static JNIEnv* GetJNIEnv(JavaVM *jvm, bool *attached) {
    *attached = false;

    if (jvm == NULL) {
      // In case jvm is accidentally NULL, we do nothing, instead of
      // terminating the thread.
      LOG(ERROR) << "Given jvm is null.";
      return NULL;
    }

    // First, try to get JNIEnv instance attached to the current thread.
    JNIEnv *env;
    jint result = jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6);
    if (result == JNI_EDETACHED) {
      // This thread is not attached to Java VM. So try to attach.
      JavaVMAttachArgs attach_args = { JNI_VERSION_1_6, NULL, NULL };
      result = jvm->AttachCurrentThread(&env, &attach_args);
      if (result != JNI_OK) {
        LOG(ERROR) << "Failed to attach Java thread.";
        return NULL;
      }

      *attached = true;
    }

    if (result != JNI_OK) {
      LOG(ERROR) << "Failed to get JNIEnv.";
      return NULL;
    }

    return env;
  }

  DISALLOW_COPY_AND_ASSIGN(ScopedJavaThreadAttacher);
};

// Creates jbyteArray instance containing the data.
jbyteArray BufferToJByteArray(
    JNIEnv *env, const void *data, const size_t size) {
  jbyteArray result = env->NewByteArray(size);
  CHECK(result);
  env->SetByteArrayRegion(
      result, 0, size, reinterpret_cast<const jbyte*>(data));
  return result;
}

// Copies the contents of the given source to buf, and store the size into
// buf_size.
// Retruns true, if finished successfully. Otherwise, false.
bool CopyJByteArrayToBuf(JNIEnv *env, const jbyteArray &source,
                         void *buf, size_t *buf_size) {
  const jsize size = env->GetArrayLength(source);
  if (size > *buf_size) {
    return false;
  }
  env->GetByteArrayRegion(source, 0, size, reinterpret_cast<jbyte*>(buf));
  *buf_size = size;
  return true;
}

void AssignJByteArrayToString(JNIEnv *env, const jbyteArray &source,
                              string *dest) {
  size_t size = env->GetArrayLength(source);
  scoped_ptr<char[]> buf(new char[size]);
  CHECK(CopyJByteArrayToBuf(env, source, buf.get(), &size));
  dest->assign(buf.get(), size);
}

const char *HTTPMethodTypeToChars(mozc::HTTPMethodType type) {
  switch (type) {
    case mozc::HTTP_GET:
      return "GET";
    case mozc::HTTP_HEAD:
      return "HEAD";
    case mozc::HTTP_POST:
      return "POST";
    default:
      LOG(ERROR) << "Invalid method; " << type;
      return NULL;
  }
}

// Utility to enlarge the java's local frame, as RAII idiom, like scoped_ptr.
class ScopedJavaLocalFrame {
 public:
  ScopedJavaLocalFrame(JNIEnv *env, jint capacity) : env_(env) {
    env_->PushLocalFrame(capacity);
  }
  ~ScopedJavaLocalFrame() {
    env_->PopLocalFrame(NULL);
  }

 private:
  JNIEnv *env_;
  DISALLOW_COPY_AND_ASSIGN(ScopedJavaLocalFrame);
};

const jint kDefaultLocalFrameSize = 16;

mozc::Mutex jvm_mutex;

class JavaHttpClientDescriptor {
 public:
  explicit JavaHttpClientDescriptor(JavaVM *jvm) : jvm_(jvm) {
    CHECK(jvm != NULL) << "Given JVM is null.";

    ScopedJavaThreadAttacher thread_attacher(jvm);
    JNIEnv *env = thread_attacher.mutable_jni_env();
    ScopedJavaLocalFrame local_frame(env, kDefaultLocalFrameSize);

    const char kHttpClientClassPath[] =
        "org/mozc/android/inputmethod/japanese/nativecallback/HttpClient";
    jclass http_Client_class = env->FindClass(kHttpClientClassPath);
    CHECK(http_Client_class != NULL)
        << kHttpClientClassPath << " is not found.";
    // We need to keep "global" reference for jclass instance, in order to
    // avoid the garbage collection of the encryptor class.
    http_client_class_ =
        static_cast<jclass>(env->NewGlobalRef(http_Client_class));

    request_id_ = env->GetStaticMethodID(
        http_client_class_, "request", "([B[B[B)[B");
  }

  ~JavaHttpClientDescriptor() {
    ScopedJavaThreadAttacher thread_attacher(jvm_);
    JNIEnv *env = thread_attacher.mutable_jni_env();
    env->DeleteGlobalRef(http_client_class_);
  }

  JavaVM *mutable_jvm() {
    return jvm_;
  }

  jbyteArray Request(JNIEnv *env,
                     jbyteArray method, jbyteArray url, jbyteArray post_data) {
    jbyteArray result = static_cast<jbyteArray>(env->CallStaticObjectMethod(
        http_client_class_, request_id_, method, url, post_data));

    if (env->ExceptionOccurred() != NULL) {
      env->ExceptionDescribe();
      env->ExceptionClear();
      return NULL;
    }

    return result;
  }

  static JavaHttpClientDescriptor *Create(JavaVM *jvm) {
    if (jvm == NULL) {
      return NULL;
    }
    return new JavaHttpClientDescriptor(jvm);
  }

 private:
  JavaVM *jvm_;
  jclass http_client_class_;
  jmethodID request_id_;

  DISALLOW_COPY_AND_ASSIGN(JavaHttpClientDescriptor);
};
scoped_ptr<JavaHttpClientDescriptor> http_client_descriptor;
}  // namespace

namespace mozc {
namespace jni {

// static
bool JavaHttpClientProxy::Request(HTTPMethodType type,
                                  const string &url,
                                  const char *post_data,
                                  size_t post_size,
                                  const HTTPClient::Option &option,
                                  string *output_string) {
  JavaHttpClientDescriptor *descriptor = http_client_descriptor.get();
  if (descriptor == NULL) {
    LOG(ERROR) << "JavaVM is not initialized.";
    return false;
  }

  ScopedJavaThreadAttacher thread_attacher(descriptor->mutable_jvm());
  JNIEnv *env = thread_attacher.mutable_jni_env();
  if (env == NULL) {
    LOG(ERROR) << "Java env is not available.";
    return false;
  }

  ScopedJavaLocalFrame local_frame(env, kDefaultLocalFrameSize);

  const char *method = HTTPMethodTypeToChars(type);
  if (!method) {
    LOG(ERROR) << "HTTP method type is not accepatable.";
    return false;
  }

  jbyteArray java_result = descriptor->Request(
      env,
      BufferToJByteArray(env, method, strlen(method)),
      BufferToJByteArray(env, url.c_str(), url.length()),
      BufferToJByteArray(env, post_data, post_size));

  if (java_result == NULL) {
    LOG(ERROR) << "Method invocation failed.";
    return false;
  }

  if (output_string) {
    AssignJByteArrayToString(env, java_result, output_string);
  }

  return true;
}

// static
void JavaHttpClientProxy::SetJavaVM(JavaVM *jvm) {
  mozc::scoped_lock lock(&jvm_mutex);
  http_client_descriptor.reset(JavaHttpClientDescriptor::Create(jvm));
}

}  // namespace jni
}  // namespace mozc
