/*
 * Copyright (C) 2011 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 <jni.h>

#include <memory>
#include <unordered_map>
#include <string>

#include "base/utilities.h"
#include "core/value.h"

#ifndef ANDROID_FILTERFW_JNI_JNI_UTIL_H
#define ANDROID_FILTERFW_JNI_JNI_UTIL_H

// We add this JNI_NULL macro to allow consistent code separation of Java and
// C++ types.
#define JNI_NULL NULL

#if 0
// Pointer to current JavaVM. Do not use this directly. Instead use the funciton
// GetCurrentJavaVM().
extern JavaVM* g_current_java_vm_;

// Wrapper around a java object pointer, which includes the environment
// pointer in which the object "lives". This is used for passing down Java
// objects from the Java layer to C++.
// While an instance of this class does not own the underlying java object, it
// does hold a global reference to it, so that the Java garbage collector does
// not destroy it. It uses reference counting to determine when it can destroy
// the reference.
// TODO: Add multi-thread support!
class JavaObject {
  public:
    // Creates a NULL JavaObject.
    JavaObject();

    // Creates a wrapper around the given object in the given JNI environment.
    JavaObject(jobject object, JNIEnv* env);

    // Copy constructor.
    JavaObject(const JavaObject& java_obj);

    // Destructor.
    ~JavaObject();

    // Assignment operator.
    JavaObject& operator=(const JavaObject& java_obj);

    // Access to the object (non-const as JNI functions are non-const).
    jobject object() const {
      return object_;
    }

    // Resets this object to the NULL JavaObject.
    void Reset();

  private:
    // Retain the instance, i.e. increase reference count.
    void Retain();

    // Release the instance, i.e. decrease reference count.
    void Release();

    // The object pointer (not owned).
    jobject object_;

    // The reference count of this object
    int* ref_count_;
};
#endif

// ObjectPool template class. This class keeps track of C++ instances that are
// coupled to Java objects. This is done by using an "id" field in the Java
// object, which is then mapped to the correct instance here. It should not be
// necessary to use this class directly. Instead, the convenience functions
// below can be used.
template<class T>
class ObjectPool {
  public:
    // Create a new ObjectPool for a specific object type. Pass the path to the
    // Java equivalent class of the C++ class, and the name of the java member
    // field that will store the object's ID.
    static void Setup(const std::string& jclass_name,
                      const std::string& id_fld_name) {
      instance_ = new ObjectPool<T>(jclass_name, id_fld_name);
    }

    // Return the shared instance to this type's pool.
    static ObjectPool* Instance() {
      return instance_;
    }

    // Delete this type's pool.
    static void TearDown() {
      delete instance_;
    }

    // Register a new C++ object with the pool. This does not affect the Java
    // layer. Use WrapObject() instead to perform the necessary Java-side
    // assignments. Pass true to owns if the object pool owns the object.
    int RegisterObject(T* object, bool owns) {
      const int id = next_id_;
      objects_[id] = object;
      owns_[id] = owns;
      ++next_id_;
      return id;
    }

    // Return the object in the pool with the specified ID.
    T* ObjectWithID(int obj_id) const {
      typename CObjMap::const_iterator iter = objects_.find(obj_id);
      return iter == objects_.end() ? NULL : iter->second;
    }

    // Get the ID of a Java object. This ID can be used to look-up the C++
    // object.
    int GetObjectID(JNIEnv* env, jobject j_object) {
      jclass cls = env->GetObjectClass(j_object);
      jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I");
      const int result = env->GetIntField(j_object, id_field);
      env->DeleteLocalRef(cls);
      return result;
    }

    // Take a C++ object and wrap it with a given Java object. This will
    // essentially set the ID member of the Java object to the ID of the C++
    // object. Pass true to owns if the object pool owns the object.
    bool WrapObject(T* c_object, JNIEnv* env, jobject j_object, bool owns) {
      const int id = RegisterObject(c_object, owns);
      jclass cls = env->GetObjectClass(j_object);
      jfieldID id_field = env->GetFieldID(cls, id_field_name_.c_str(), "I");
      env->SetIntField(j_object, id_field, id);
      env->DeleteLocalRef(cls);
      return true;
    }

    // Remove the object with the given ID from this pool, and delete it. This
    // does not affect the Java layer.
    bool DeleteObjectWithID(int obj_id) {
      typename CObjMap::iterator iter = objects_.find(obj_id);
      const bool found = iter != objects_.end();
      if (found) {
        if (owns_[obj_id])
          delete iter->second;
        objects_.erase(iter);
      }
      return found;
    }

    // Instantiates a new java object for this class. The Java class must have
    // a default constructor for this to succeed.
    jobject CreateJavaObject(JNIEnv* env) {
      jclass cls = env->FindClass(jclass_name_.c_str());
      jmethodID constructor = env->GetMethodID(
        cls,
        "<init>",
        "(Landroid/filterfw/core/NativeAllocatorTag;)V");
      jobject result = env->NewObject(cls, constructor, JNI_NULL);
      env->DeleteLocalRef(cls);
      return result;
    }

    int GetObjectCount() const {
      return objects_.size();
    }

    const std::string& GetJavaClassName() const {
      return jclass_name_;
    }

  private:
    explicit ObjectPool(const std::string& jclass_name,
                        const std::string& id_fld_name)
      : jclass_name_(jclass_name),
        id_field_name_(id_fld_name),
        next_id_(0) { }

    typedef std::unordered_map<int, T*>    CObjMap;
    typedef std::unordered_map<int, bool>  FlagMap;
    static ObjectPool* instance_;
    std::string jclass_name_;
    std::string id_field_name_;
    int next_id_;
    CObjMap objects_;
    FlagMap owns_;

    DISALLOW_COPY_AND_ASSIGN(ObjectPool);
};

template<typename T> ObjectPool<T>* ObjectPool<T>::instance_ = NULL;

// Convenience Functions ///////////////////////////////////////////////////////

// This function "links" the C++ instance and the Java instance, so that they
// can be mapped to one another. This must be called for every C++ instance
// which is wrapped by a Java front-end interface. Pass true to owns, if the
// Java layer should own the object.
template<typename T>
bool WrapObjectInJava(T* c_object, JNIEnv* env, jobject j_object, bool owns) {
  ObjectPool<T>* pool = ObjectPool<T>::Instance();
  return pool ? pool->WrapObject(c_object, env, j_object, owns) : false;
}

// Calls WrapObjectInJava, safely freeing c_object if object creation fails.
template<typename T>
bool WrapOwnedObjectInJava(std::unique_ptr<T> c_object, JNIEnv* env,
                           jobject j_object, bool owns) {
  if (!WrapObjectInJava<T>(c_object.get(), env, j_object, owns))
    return false;
  // If we succeeded, a Java object now owns our c object; don't free it.
  c_object.release();
  return true;
}

// Creates a new Java instance, which wraps the passed C++ instance. Returns
// the wrapped object or JNI_NULL if there was an error. Pass true to owns, if
// the Java layer should own the object.
template<typename T>
jobject WrapNewObjectInJava(T* c_object, JNIEnv* env, bool owns) {
  ObjectPool<T>* pool = ObjectPool<T>::Instance();
  if (pool) {
    jobject result = pool->CreateJavaObject(env);
    if (WrapObjectInJava(c_object, env, result, owns))
      return result;
  }
  return JNI_NULL;
}

// Use ConvertFromJava to obtain a C++ instance given a Java object. This
// instance must have been wrapped in Java using the WrapObjectInJava()
// function.
template<typename T>
T* ConvertFromJava(JNIEnv* env, jobject j_object) {
  ObjectPool<T>* pool = ObjectPool<T>::Instance();
  return pool && j_object
    ? pool->ObjectWithID(pool->GetObjectID(env, j_object))
    : NULL;
}

// Delete the native object given a Java instance. This should be called from
// the Java object's finalizer.
template<typename T>
bool DeleteNativeObject(JNIEnv* env, jobject j_object) {
  ObjectPool<T>* pool = ObjectPool<T>::Instance();
  return pool && j_object
    ? pool->DeleteObjectWithID(pool->GetObjectID(env, j_object))
    : false;
}

#if 0
// Get the current JNI VM, or NULL if there is no current VM
JavaVM* GetCurrentJavaVM();

// Get the current JNI environment, or NULL if this is not a JNI thread
JNIEnv* GetCurrentJNIEnv();
#endif

// Convert C++ boolean to Java boolean.
jboolean ToJBool(bool value);

// Convert Java boolean to C++ boolean.
bool ToCppBool(jboolean value);

// Convert Java String to C++ string.
jstring ToJString(JNIEnv* env, const std::string& value);

// Convert C++ string to Java String.
std::string ToCppString(JNIEnv* env, jstring value);

// Convert Java object to a (C) Value object.
Value ToCValue(JNIEnv* env, jobject object);

// Convert a (C) Value object to a Java object.
jobject ToJObject(JNIEnv* env, const Value& value);

// Returns true, iff the passed object is an instance of the class specified
// by its fully qualified class name.
bool IsJavaInstanceOf(JNIEnv* env, jobject object,
                      const std::string& class_name);

#endif // ANDROID_FILTERFW_JNI_JNI_UTIL_H
