/*
 * Copyright (C) 2014 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 <sstream>

#include "common_runtime_test.h"
#include "handle_scope-inl.h"
#include "mirror/class-alloc-inl.h"
#include "mirror/class-inl.h"
#include "reference_queue.h"
#include "scoped_thread_state_change-inl.h"

namespace art {
namespace gc {

class ReferenceQueueTest : public CommonRuntimeTest {
 protected:
  ReferenceQueueTest() {
    use_boot_image_ = true;  // Make the Runtime creation cheaper.
  }
};

TEST_F(ReferenceQueueTest, EnqueueDequeue) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  StackHandleScope<20> hs(self);
  Mutex lock("Reference queue lock");
  ReferenceQueue queue(&lock);
  ASSERT_TRUE(queue.IsEmpty());
  ASSERT_EQ(queue.GetLength(), 0U);
  auto ref_class = hs.NewHandle(
      Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;",
                                                      ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(ref_class != nullptr);
  auto ref1(hs.NewHandle(ref_class->AllocObject(self)->AsReference()));
  ASSERT_TRUE(ref1 != nullptr);
  auto ref2(hs.NewHandle(ref_class->AllocObject(self)->AsReference()));
  ASSERT_TRUE(ref2 != nullptr);
  queue.EnqueueReference(ref1.Get());
  ASSERT_TRUE(!queue.IsEmpty());
  ASSERT_EQ(queue.GetLength(), 1U);
  queue.EnqueueReference(ref2.Get());
  ASSERT_TRUE(!queue.IsEmpty());
  ASSERT_EQ(queue.GetLength(), 2U);

  std::set<mirror::Reference*> refs = {ref1.Get(), ref2.Get()};
  std::set<mirror::Reference*> dequeued;
  dequeued.insert(queue.DequeuePendingReference().Ptr());
  ASSERT_TRUE(!queue.IsEmpty());
  ASSERT_EQ(queue.GetLength(), 1U);
  dequeued.insert(queue.DequeuePendingReference().Ptr());
  ASSERT_EQ(queue.GetLength(), 0U);
  ASSERT_TRUE(queue.IsEmpty());
  ASSERT_EQ(refs, dequeued);
}

TEST_F(ReferenceQueueTest, Dump) {
  Thread* self = Thread::Current();
  ScopedObjectAccess soa(self);
  StackHandleScope<20> hs(self);
  Mutex lock("Reference queue lock");
  ReferenceQueue queue(&lock);
  std::ostringstream oss;
  queue.Dump(oss);
  LOG(INFO) << oss.str();
  auto weak_ref_class = hs.NewHandle(
      Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/WeakReference;",
                                                      ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(weak_ref_class != nullptr);
  auto finalizer_ref_class = hs.NewHandle(
      Runtime::Current()->GetClassLinker()->FindClass(self, "Ljava/lang/ref/FinalizerReference;",
                                                      ScopedNullHandle<mirror::ClassLoader>()));
  ASSERT_TRUE(finalizer_ref_class != nullptr);
  auto ref1(hs.NewHandle(weak_ref_class->AllocObject(self)->AsReference()));
  ASSERT_TRUE(ref1 != nullptr);
  auto ref2(hs.NewHandle(finalizer_ref_class->AllocObject(self)->AsReference()));
  ASSERT_TRUE(ref2 != nullptr);

  queue.EnqueueReference(ref1.Get());
  oss.str("");
  queue.Dump(oss);
  LOG(INFO) << oss.str();

  queue.EnqueueReference(ref2.Get());
  oss.str("");
  queue.Dump(oss);
  LOG(INFO) << oss.str();
}

}  // namespace gc
}  // namespace art
