// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/android/scoped_java_ref.h"

#include <iterator>
#include <type_traits>

#include "base/android/jni_android.h"
#include "base/android/jni_string.h"
#include "testing/gtest/include/gtest/gtest.h"

#define EXPECT_SAME_OBJECT(a, b) \
  EXPECT_TRUE(env->IsSameObject((a).obj(), (b).obj()))

namespace base {
namespace android {

namespace {
int g_local_refs = 0;
int g_global_refs = 0;

const JNINativeInterface* g_previous_functions;

jobject NewGlobalRef(JNIEnv* env, jobject obj) {
  ++g_global_refs;
  return g_previous_functions->NewGlobalRef(env, obj);
}

void DeleteGlobalRef(JNIEnv* env, jobject obj) {
  --g_global_refs;
  return g_previous_functions->DeleteGlobalRef(env, obj);
}

jobject NewLocalRef(JNIEnv* env, jobject obj) {
  ++g_local_refs;
  return g_previous_functions->NewLocalRef(env, obj);
}

void DeleteLocalRef(JNIEnv* env, jobject obj) {
  --g_local_refs;
  return g_previous_functions->DeleteLocalRef(env, obj);
}
}  // namespace

class ScopedJavaRefTest : public testing::Test {
 protected:
  void SetUp() override {
    g_local_refs = 0;
    g_global_refs = 0;
    JNIEnv* env = AttachCurrentThread();
    g_previous_functions = env->functions;
    hooked_functions = *g_previous_functions;
    env->functions = &hooked_functions;
    // We inject our own functions in JNINativeInterface so we can keep track
    // of the reference counting ourselves.
    hooked_functions.NewGlobalRef = &NewGlobalRef;
    hooked_functions.DeleteGlobalRef = &DeleteGlobalRef;
    hooked_functions.NewLocalRef = &NewLocalRef;
    hooked_functions.DeleteLocalRef = &DeleteLocalRef;
  }

  void TearDown() override {
    JNIEnv* env = AttachCurrentThread();
    env->functions = g_previous_functions;
  }
  // From JellyBean release, the instance of this struct provided in JNIEnv is
  // read-only, so we deep copy it to allow individual functions to be hooked.
  JNINativeInterface hooked_functions;
};

// The main purpose of this is testing the various conversions compile.
TEST_F(ScopedJavaRefTest, Conversions) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jstring> str = ConvertUTF8ToJavaString(env, "string");
  ScopedJavaGlobalRef<jstring> global(str);

  // Contextual conversions to bool should be allowed.
  EXPECT_TRUE(str);
  EXPECT_FALSE(JavaRef<jobject>());

  // All the types should convert from nullptr, even JavaRef.
  {
    JavaRef<jstring> null_ref(nullptr);
    EXPECT_FALSE(null_ref);
    ScopedJavaLocalRef<jobject> null_local(nullptr);
    EXPECT_FALSE(null_local);
    ScopedJavaGlobalRef<jarray> null_global(nullptr);
    EXPECT_FALSE(null_global);
  }

  // Local and global refs should {copy,move}-{construct,assign}.
  // Moves should leave the source as null.
  {
    ScopedJavaLocalRef<jstring> str2(str);
    EXPECT_SAME_OBJECT(str2, str);
    ScopedJavaLocalRef<jstring> str3(std::move(str2));
    EXPECT_SAME_OBJECT(str3, str);
    EXPECT_FALSE(str2);
    ScopedJavaLocalRef<jstring> str4;
    str4 = str;
    EXPECT_SAME_OBJECT(str4, str);
    ScopedJavaLocalRef<jstring> str5;
    str5 = std::move(str4);
    EXPECT_SAME_OBJECT(str5, str);
    EXPECT_FALSE(str4);
  }
  {
    ScopedJavaGlobalRef<jstring> str2(global);
    EXPECT_SAME_OBJECT(str2, str);
    ScopedJavaGlobalRef<jstring> str3(std::move(str2));
    EXPECT_SAME_OBJECT(str3, str);
    EXPECT_FALSE(str2);
    ScopedJavaGlobalRef<jstring> str4;
    str4 = global;
    EXPECT_SAME_OBJECT(str4, str);
    ScopedJavaGlobalRef<jstring> str5;
    str5 = std::move(str4);
    EXPECT_SAME_OBJECT(str5, str);
    EXPECT_FALSE(str4);
  }

  // As above but going from jstring to jobject.
  {
    ScopedJavaLocalRef<jobject> obj2(str);
    EXPECT_SAME_OBJECT(obj2, str);
    ScopedJavaLocalRef<jobject> obj3(std::move(obj2));
    EXPECT_SAME_OBJECT(obj3, str);
    EXPECT_FALSE(obj2);
    ScopedJavaLocalRef<jobject> obj4;
    obj4 = str;
    EXPECT_SAME_OBJECT(obj4, str);
    ScopedJavaLocalRef<jobject> obj5;
    obj5 = std::move(obj4);
    EXPECT_SAME_OBJECT(obj5, str);
    EXPECT_FALSE(obj4);
  }
  {
    ScopedJavaGlobalRef<jobject> obj2(global);
    EXPECT_SAME_OBJECT(obj2, str);
    ScopedJavaGlobalRef<jobject> obj3(std::move(obj2));
    EXPECT_SAME_OBJECT(obj3, str);
    EXPECT_FALSE(obj2);
    ScopedJavaGlobalRef<jobject> obj4;
    obj4 = global;
    EXPECT_SAME_OBJECT(obj4, str);
    ScopedJavaGlobalRef<jobject> obj5;
    obj5 = std::move(obj4);
    EXPECT_SAME_OBJECT(obj5, str);
    EXPECT_FALSE(obj4);
  }

  // Explicit copy construction or assignment between global<->local is allowed,
  // but not implicit conversions.
  {
    ScopedJavaLocalRef<jstring> new_local(global);
    EXPECT_SAME_OBJECT(new_local, str);
    new_local = global;
    EXPECT_SAME_OBJECT(new_local, str);
    ScopedJavaGlobalRef<jstring> new_global(str);
    EXPECT_SAME_OBJECT(new_global, str);
    new_global = str;
    EXPECT_SAME_OBJECT(new_local, str);
    static_assert(!std::is_convertible<ScopedJavaLocalRef<jobject>,
                                       ScopedJavaGlobalRef<jobject>>::value,
                  "");
    static_assert(!std::is_convertible<ScopedJavaGlobalRef<jobject>,
                                       ScopedJavaLocalRef<jobject>>::value,
                  "");
  }

  // Converting between local/global while also converting to jobject also works
  // because JavaRef<jobject> is the base class.
  {
    ScopedJavaGlobalRef<jobject> global_obj(str);
    ScopedJavaLocalRef<jobject> local_obj(global);
    const JavaRef<jobject>& obj_ref1(str);
    const JavaRef<jobject>& obj_ref2(global);
    EXPECT_SAME_OBJECT(obj_ref1, obj_ref2);
    EXPECT_SAME_OBJECT(global_obj, obj_ref2);
  }
  global.Reset(str);
  const JavaRef<jstring>& str_ref = str;
  EXPECT_EQ("string", ConvertJavaStringToUTF8(str_ref));
  str.Reset();
}

TEST_F(ScopedJavaRefTest, RefCounts) {
  JNIEnv* env = AttachCurrentThread();
  ScopedJavaLocalRef<jstring> str;
  // The ConvertJavaStringToUTF8 below creates a new string that would normally
  // return a local ref. We simulate that by starting the g_local_refs count at
  // 1.
  g_local_refs = 1;
  str.Reset(ConvertUTF8ToJavaString(env, "string"));
  EXPECT_EQ(1, g_local_refs);
  EXPECT_EQ(0, g_global_refs);
  {
    ScopedJavaGlobalRef<jstring> global_str(str);
    ScopedJavaGlobalRef<jobject> global_obj(global_str);
    EXPECT_EQ(1, g_local_refs);
    EXPECT_EQ(2, g_global_refs);

    auto str2 = ScopedJavaLocalRef<jstring>::Adopt(env, str.Release());
    EXPECT_EQ(1, g_local_refs);
    {
      ScopedJavaLocalRef<jstring> str3(str2);
      EXPECT_EQ(2, g_local_refs);
    }
    EXPECT_EQ(1, g_local_refs);
    {
      ScopedJavaLocalRef<jstring> str4((ScopedJavaLocalRef<jstring>(str2)));
      EXPECT_EQ(2, g_local_refs);
    }
    EXPECT_EQ(1, g_local_refs);
    {
      ScopedJavaLocalRef<jstring> str5;
      str5 = ScopedJavaLocalRef<jstring>(str2);
      EXPECT_EQ(2, g_local_refs);
    }
    EXPECT_EQ(1, g_local_refs);
    str2.Reset();
    EXPECT_EQ(0, g_local_refs);
    global_str.Reset();
    EXPECT_EQ(1, g_global_refs);
    ScopedJavaGlobalRef<jobject> global_obj2(global_obj);
    EXPECT_EQ(2, g_global_refs);
  }

  EXPECT_EQ(0, g_local_refs);
  EXPECT_EQ(0, g_global_refs);
}

class JavaObjectArrayReaderTest : public testing::Test {
 protected:
  void SetUp() override {
    JNIEnv* env = AttachCurrentThread();
    int_class_ = GetClass(env, "java/lang/Integer");
    int_constructor_ = MethodID::Get<MethodID::TYPE_INSTANCE>(
        env, int_class_.obj(), "<init>", "(I)V");
    array_ = MakeArray(array_len_);

    // Make array_len_ different Integer objects, keep a reference to each,
    // and add them to the array.
    for (jint i = 0; i < array_len_; ++i) {
      jobject member = env->NewObject(int_class_.obj(), int_constructor_, i);
      ASSERT_NE(member, nullptr);
      array_members_[i] = ScopedJavaLocalRef<jobject>::Adopt(env, member);
      env->SetObjectArrayElement(array_.obj(), i, member);
    }
  }

  // Make an Integer[] with len elements, all initialized to null.
  ScopedJavaLocalRef<jobjectArray> MakeArray(jsize len) {
    JNIEnv* env = AttachCurrentThread();
    jobjectArray array = env->NewObjectArray(len, int_class_.obj(), nullptr);
    EXPECT_NE(array, nullptr);
    return ScopedJavaLocalRef<jobjectArray>::Adopt(env, array);
  }

  static constexpr jsize array_len_ = 10;
  ScopedJavaLocalRef<jclass> int_class_;
  jmethodID int_constructor_;
  ScopedJavaLocalRef<jobject> array_members_[array_len_];
  ScopedJavaLocalRef<jobjectArray> array_;
};

// Must actually define the variable until C++17 :(
constexpr jsize JavaObjectArrayReaderTest::array_len_;

TEST_F(JavaObjectArrayReaderTest, ZeroLengthArray) {
  JavaObjectArrayReader<jobject> zero_length(MakeArray(0));
  EXPECT_TRUE(zero_length.empty());
  EXPECT_EQ(zero_length.size(), 0);
  EXPECT_EQ(zero_length.begin(), zero_length.end());
}

// Verify that we satisfy the C++ "InputIterator" named requirements.
TEST_F(JavaObjectArrayReaderTest, InputIteratorRequirements) {
  typedef JavaObjectArrayReader<jobject>::iterator It;

  JNIEnv* env = AttachCurrentThread();
  JavaObjectArrayReader<jobject> reader(array_);
  It i = reader.begin();

  EXPECT_TRUE(std::is_copy_constructible<It>::value);
  It copy = i;
  EXPECT_EQ(copy, i);
  EXPECT_EQ(It(i), i);

  EXPECT_TRUE(std::is_copy_assignable<It>::value);
  It assign = reader.end();
  It& assign2 = (assign = i);
  EXPECT_EQ(assign, i);
  EXPECT_EQ(assign2, assign);

  EXPECT_TRUE(std::is_destructible<It>::value);

  // Swappable
  It left = reader.begin(), right = reader.end();
  std::swap(left, right);
  EXPECT_EQ(left, reader.end());
  EXPECT_EQ(right, reader.begin());

  // Basic check that iterator_traits works
  bool same_type = std::is_same<std::iterator_traits<It>::iterator_category,
                                std::input_iterator_tag>::value;
  EXPECT_TRUE(same_type);

  // Comparisons
  EXPECT_EQ(reader.begin(), reader.begin());
  EXPECT_NE(reader.begin(), reader.end());

  // Dereferencing
  ScopedJavaLocalRef<jobject> o = *(reader.begin());
  EXPECT_SAME_OBJECT(o, array_members_[0]);
  EXPECT_TRUE(env->IsSameObject(o.obj(), reader.begin()->obj()));

  // Incrementing
  It preinc = ++(reader.begin());
  EXPECT_SAME_OBJECT(*preinc, array_members_[1]);
  It postinc = reader.begin();
  EXPECT_SAME_OBJECT(*postinc++, array_members_[0]);
  EXPECT_SAME_OBJECT(*postinc, array_members_[1]);
}

// Check that range-based for and the convenience function work as expected.
TEST_F(JavaObjectArrayReaderTest, RangeBasedFor) {
  JNIEnv* env = AttachCurrentThread();

  int i = 0;
  for (ScopedJavaLocalRef<jobject> element : array_.ReadElements<jobject>()) {
    EXPECT_SAME_OBJECT(element, array_members_[i++]);
  }
  EXPECT_EQ(i, array_len_);
}

}  // namespace android
}  // namespace base
