/*
 * 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 "reference_table.h"

#include <regex>  // NOLINT [build/c++11] [5]

#include "android-base/stringprintf.h"

#include "art_method-inl.h"
#include "class_linker.h"
#include "common_runtime_test.h"
#include "handle_scope-inl.h"
#include "mirror/array-inl.h"
#include "mirror/class-inl.h"
#include "mirror/class_loader.h"
#include "mirror/string.h"
#include "primitive.h"
#include "runtime.h"
#include "scoped_thread_state_change-inl.h"
#include "thread-current-inl.h"
#include "well_known_classes.h"

namespace art {

using android::base::StringPrintf;

class ReferenceTableTest : public CommonRuntimeTest {};

static mirror::Object* CreateWeakReference(mirror::Object* referent)
    REQUIRES_SHARED(Locks::mutator_lock_) {
  Thread* self = Thread::Current();
  ClassLinker* class_linker = Runtime::Current()->GetClassLinker();

  StackHandleScope<3> scope(self);
  Handle<mirror::Object> h_referent(scope.NewHandle<mirror::Object>(referent));

  Handle<mirror::Class> h_ref_class(scope.NewHandle<mirror::Class>(
      class_linker->FindClass(self,
                              "Ljava/lang/ref/WeakReference;",
                              ScopedNullHandle<mirror::ClassLoader>())));
  CHECK(h_ref_class != nullptr);
  CHECK(class_linker->EnsureInitialized(self, h_ref_class, true, true));

  Handle<mirror::Object> h_ref_instance(scope.NewHandle<mirror::Object>(
      h_ref_class->AllocObject(self)));
  CHECK(h_ref_instance != nullptr);

  ArtMethod* constructor = h_ref_class->FindConstructor(
      "(Ljava/lang/Object;)V", class_linker->GetImagePointerSize());
  CHECK(constructor != nullptr);

  uint32_t args[2];
  args[0] = PointerToLowMemUInt32(h_ref_instance.Get());
  args[1] = PointerToLowMemUInt32(h_referent.Get());
  JValue result;
  constructor->Invoke(self, args, sizeof(uint32_t), &result, constructor->GetShorty());
  CHECK(!self->IsExceptionPending());

  return h_ref_instance.Get();
}

TEST_F(ReferenceTableTest, Basics) {
  ScopedObjectAccess soa(Thread::Current());
  mirror::Object* o1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello");

  ReferenceTable rt("test", 0, 11);

  // Check dumping the empty table.
  {
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_NE(oss.str().find("(empty)"), std::string::npos) << oss.str();
    EXPECT_EQ(0U, rt.Size());
  }

  // Check removal of all nullss in a empty table is a no-op.
  rt.Remove(nullptr);
  EXPECT_EQ(0U, rt.Size());

  // Check removal of all o1 in a empty table is a no-op.
  rt.Remove(o1);
  EXPECT_EQ(0U, rt.Size());

  // Add o1 and check we have 1 element and can dump.
  {
    rt.Add(o1);
    EXPECT_EQ(1U, rt.Size());
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_NE(oss.str().find("1 of java.lang.String"), std::string::npos) << oss.str();
    EXPECT_EQ(oss.str().find("short[]"), std::string::npos) << oss.str();
  }

  // Add a second object 10 times and check dumping is sane.
  mirror::Object* o2 = mirror::ShortArray::Alloc(soa.Self(), 0);
  for (size_t i = 0; i < 10; ++i) {
    rt.Add(o2);
    EXPECT_EQ(i + 2, rt.Size());
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_NE(oss.str().find(StringPrintf("Last %zd entries (of %zd):",
                                          i + 2 > 10 ? 10 : i + 2,
                                          i + 2)),
              std::string::npos) << oss.str();
    EXPECT_NE(oss.str().find("1 of java.lang.String"), std::string::npos) << oss.str();
    if (i == 0) {
      EXPECT_NE(oss.str().find("1 of short[]"), std::string::npos) << oss.str();
    } else {
      EXPECT_NE(oss.str().find(StringPrintf("%zd of short[] (1 unique instances)", i + 1)),
                std::string::npos) << oss.str();
    }
  }

  // Remove o1 (first element).
  {
    rt.Remove(o1);
    EXPECT_EQ(10U, rt.Size());
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_EQ(oss.str().find("java.lang.String"), std::string::npos) << oss.str();
  }

  // Remove o2 ten times.
  for (size_t i = 0; i < 10; ++i) {
    rt.Remove(o2);
    EXPECT_EQ(9 - i, rt.Size());
    std::ostringstream oss;
    rt.Dump(oss);
    if (i == 9) {
      EXPECT_EQ(oss.str().find("short[]"), std::string::npos) << oss.str();
    } else if (i == 8) {
      EXPECT_NE(oss.str().find("1 of short[]"), std::string::npos) << oss.str();
    } else {
      EXPECT_NE(oss.str().find(StringPrintf("%zd of short[] (1 unique instances)", 10 - i - 1)),
                std::string::npos) << oss.str();
    }
  }

  // Add a reference and check that the type of the referent is dumped.
  {
    mirror::Object* empty_reference = CreateWeakReference(nullptr);
    ASSERT_TRUE(empty_reference->IsReferenceInstance());
    rt.Add(empty_reference);
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_NE(oss.str().find("java.lang.ref.WeakReference (referent is null)"), std::string::npos)
        << oss.str();
    rt.Remove(empty_reference);
  }

  {
    mirror::Object* string_referent = mirror::String::AllocFromModifiedUtf8(Thread::Current(), "A");
    mirror::Object* non_empty_reference = CreateWeakReference(string_referent);
    ASSERT_TRUE(non_empty_reference->IsReferenceInstance());
    rt.Add(non_empty_reference);
    std::ostringstream oss;
    rt.Dump(oss);
    EXPECT_NE(oss.str().find("java.lang.ref.WeakReference (referent is a java.lang.String)"),
              std::string::npos)
        << oss.str();
    rt.Remove(non_empty_reference);
  }

  // Add two objects. Enable allocation tracking for the latter.
  {
    StackHandleScope<3> hs(soa.Self());
    Handle<mirror::String> h_without_trace(hs.NewHandle(
        mirror::String::AllocFromModifiedUtf8(soa.Self(), "Without")));

    {
      ScopedThreadSuspension sts(soa.Self(), ThreadState::kSuspended);
      gc::AllocRecordObjectMap::SetAllocTrackingEnabled(true);
    }

    // To get a stack, actually make a call. Use substring, that's simple. Calling through JNI
    // avoids having to create the low-level args array ourselves.
    Handle<mirror::Object> h_with_trace;
    {
      jmethodID substr = soa.Env()->GetMethodID(WellKnownClasses::java_lang_String,
                                                "substring",
                                                "(II)Ljava/lang/String;");
      ASSERT_TRUE(substr != nullptr);
      jobject jobj = soa.Env()->AddLocalReference<jobject>(h_without_trace.Get());
      ASSERT_TRUE(jobj != nullptr);
      jobject result = soa.Env()->CallObjectMethod(jobj,
                                                   substr,
                                                   static_cast<jint>(0),
                                                   static_cast<jint>(4));
      ASSERT_TRUE(result != nullptr);
      h_with_trace = hs.NewHandle(soa.Self()->DecodeJObject(result));
    }

    Handle<mirror::Object> h_ref;
    {
      jclass weak_ref_class = soa.Env()->FindClass("java/lang/ref/WeakReference");
      ASSERT_TRUE(weak_ref_class != nullptr);
      jmethodID init = soa.Env()->GetMethodID(weak_ref_class,
                                              "<init>",
                                              "(Ljava/lang/Object;)V");
      ASSERT_TRUE(init != nullptr);
      jobject referent = soa.Env()->AddLocalReference<jobject>(h_with_trace.Get());
      jobject result = soa.Env()->NewObject(weak_ref_class, init, referent);
      ASSERT_TRUE(result != nullptr);
      h_ref = hs.NewHandle(soa.Self()->DecodeJObject(result));
    }

    rt.Add(h_without_trace.Get());
    rt.Add(h_with_trace.Get());
    rt.Add(h_ref.Get());

    std::ostringstream oss;
    rt.Dump(oss);

    constexpr const char* kStackTracePattern =
        R"(test reference table dump:\n)"
        R"(  Last 3 entries \(of 3\):\n)"  // NOLINT
        R"(        2: 0x[0-9a-f]* java.lang.ref.WeakReference \(referent is a java.lang.String\)\n)"  // NOLINT
        R"(          Allocated at:\n)"
        R"(            \(No managed frames\)\n)"  // NOLINT
        R"(          Referent allocated at:\n)"
        R"(            java.lang.String java.lang.String.fastSubstring\(int, int\):-2\n)"  // NOLINT
        R"(            java.lang.String java.lang.String.substring\(int, int\):[0-9]*\n)"  // NOLINT
        R"(        1: 0x[0-9a-f]* java.lang.String "With"\n)"
        R"(          Allocated at:\n)"
        R"(            java.lang.String java.lang.String.fastSubstring\(int, int\):-2\n)"  // NOLINT
        R"(            java.lang.String java.lang.String.substring\(int, int\):[0-9]*\n)"  // NOLINT
        R"(        0: 0x[0-9a-f]* java.lang.String "Without"\n)"
        R"(  Summary:\n)"
        R"(        2 of java.lang.String \(2 unique instances\)\n)"  // NOLINT
        R"(        1 of java.lang.ref.WeakReference\n)";
    std::regex stack_trace_regex(kStackTracePattern);
    std::smatch stack_trace_match;
    std::string str = oss.str();
    bool found = std::regex_search(str, stack_trace_match, stack_trace_regex);
    EXPECT_TRUE(found) << str;

    {
      ScopedThreadSuspension sts(soa.Self(), ThreadState::kSuspended);
      gc::AllocRecordObjectMap::SetAllocTrackingEnabled(false);
    }
  }
}

static std::vector<size_t> FindAll(const std::string& haystack, const char* needle) {
  std::vector<size_t> res;
  size_t start = 0;
  do {
    size_t pos = haystack.find(needle, start);
    if (pos == std::string::npos) {
      break;
    }
    res.push_back(pos);
    start = pos + 1;
  } while (start < haystack.size());
  return res;
}

TEST_F(ReferenceTableTest, SummaryOrder) {
  // Check that the summary statistics are sorted.
  ScopedObjectAccess soa(Thread::Current());

  ReferenceTable rt("test", 0, 20);

  {
    mirror::Object* s1 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "hello");
    mirror::Object* s2 = mirror::String::AllocFromModifiedUtf8(soa.Self(), "world");

    // 3 copies of s1, 2 copies of s2, interleaved.
    for (size_t i = 0; i != 2; ++i) {
      rt.Add(s1);
      rt.Add(s2);
    }
    rt.Add(s1);
  }

  {
    // Differently sized byte arrays. Should be sorted by identical (non-unique cound).
    mirror::Object* b1_1 = mirror::ByteArray::Alloc(soa.Self(), 1);
    rt.Add(b1_1);
    rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2));
    rt.Add(b1_1);
    rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2));
    rt.Add(mirror::ByteArray::Alloc(soa.Self(), 1));
    rt.Add(mirror::ByteArray::Alloc(soa.Self(), 2));
  }

  rt.Add(mirror::CharArray::Alloc(soa.Self(), 0));

  // Now dump, and ensure order.
  std::ostringstream oss;
  rt.Dump(oss);

  // Only do this on the part after Summary.
  std::string base = oss.str();
  size_t summary_pos = base.find("Summary:");
  ASSERT_NE(summary_pos, std::string::npos);

  std::string haystack = base.substr(summary_pos);

  std::vector<size_t> strCounts = FindAll(haystack, "java.lang.String");
  std::vector<size_t> b1Counts = FindAll(haystack, "byte[] (1 elements)");
  std::vector<size_t> b2Counts = FindAll(haystack, "byte[] (2 elements)");
  std::vector<size_t> cCounts = FindAll(haystack, "char[]");

  // Only one each.
  EXPECT_EQ(1u, strCounts.size());
  EXPECT_EQ(1u, b1Counts.size());
  EXPECT_EQ(1u, b2Counts.size());
  EXPECT_EQ(1u, cCounts.size());

  // Expect them to be in order.
  EXPECT_LT(strCounts[0], b1Counts[0]);
  EXPECT_LT(b1Counts[0], b2Counts[0]);
  EXPECT_LT(b2Counts[0], cCounts[0]);
}

}  // namespace art
