// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// 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 "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);
}

}  // namespace android
}  // namespace base
