// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// 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 "starboard/memory_reporter.h"
#include "starboard/common/mutex.h"
#include "starboard/configuration.h"
#include "starboard/memory.h"
#include "starboard/thread.h"
#include "starboard/time.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace starboard {
namespace nplb {
namespace {

// This thread local boolean is used to filter allocations and
// 1) Prevent allocations from other threads.
// 2) Selectively disable allocations so that unintended allocs from
//    gTest (ASSERT_XXX) don't cause the current test to fail.
void InitMemoryTrackingState_ThreadLocal();
bool GetMemoryTrackingEnabled_ThreadLocal();
void SetMemoryTrackingEnabled_ThreadLocal(bool value);

// Scoped object that temporary turns off MemoryTracking. This is needed
// to avoid allocations from gTest being inserted into the memory tracker.
struct NoMemTracking {
  bool prev_val;
  NoMemTracking() {
    prev_val = GetMemoryTrackingEnabled_ThreadLocal();
    SetMemoryTrackingEnabled_ThreadLocal(false);
  }
  ~NoMemTracking() { SetMemoryTrackingEnabled_ThreadLocal(prev_val); }
};

// EXPECT_XXX and ASSERT_XXX allocate memory, a big no-no when
// for unit testing allocations. These overrides disable memory
// tracking for the duration of the EXPECT and ASSERT operations.
#define EXPECT_EQ_NO_TRACKING(A, B)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    EXPECT_EQ(A, B);                                \
  }

#define EXPECT_NE_NO_TRACKING(A, B)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    EXPECT_NE(A, B);                                \
  }

#define EXPECT_TRUE_NO_TRACKING(A)                  \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    EXPECT_TRUE(A);                                 \
  }

#define EXPECT_FALSE_NO_TRACKING(A)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    EXPECT_FALSE(A);                                \
  }

#define ASSERT_EQ_NO_TRACKING(A, B)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    ASSERT_EQ(A, B);                                \
  }

#define ASSERT_NE_NO_TRACKING(A, B)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    ASSERT_NE(A, B);                                \
  }

#define ASSERT_TRUE_NO_TRACKING(A)                  \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    ASSERT_TRUE(A);                                 \
  }

#define ASSERT_FALSE_NO_TRACKING(A)                 \
  {                                                 \
    NoMemTracking no_memory_tracking_in_this_scope; \
    ASSERT_FALSE(A);                                \
  }

// A structure that cannot be allocated because it throws an exception in its
// constructor. This is needed to test the std::nothrow version of delete since
// it is only called when the std::nothrow version of new fails.
struct ThrowConstructor {
  // ThrowConstructor() throw(std::exception) { throw std::exception(); }
  ThrowConstructor() : foo_(1) { throw std::exception(); }
  // Required to prevent the constructor from being inlined and optimized away.
  volatile int foo_;
};

///////////////////////////////////////////////////////////////////////////////
// A memory reporter that is used to watch allocations from the system.
class TestMemReporter {
 public:
  TestMemReporter() { Construct(); }

  SbMemoryReporter* memory_reporter() { return &memory_reporter_; }

  // Removes this object from listening to allocations.
  void RemoveGlobalHooks() {
    SbMemorySetReporter(NULL);
    // Sleep to allow other threads time to pass through.
    SbThreadSleep(250 * kSbTimeMillisecond);
  }

  // Total number allocations outstanding.
  int number_allocs() const { return number_allocs_; }

  // Total number memory map outstanding.
  int number_map_mem() const { return number_map_mem_; }

  void Clear() {
    starboard::ScopedLock lock(mutex_);
    number_allocs_ = 0;
    number_map_mem_ = 0;
    last_allocation_ = NULL;
    last_deallocation_ = NULL;
    last_mem_map_ = NULL;
    last_mem_unmap_ = NULL;
  }

  const void* last_allocation() const { return last_allocation_; }
  const void* last_deallocation() const { return last_deallocation_; }
  const void* last_mem_map() const { return last_mem_map_; }
  const void* last_mem_unmap() const { return last_mem_unmap_; }

 private:
  // Boilerplate to delegate static function callbacks to the class instance.
  static void OnMalloc(void* context, const void* memory, size_t size) {
    TestMemReporter* t = static_cast<TestMemReporter*>(context);
    t->ReportAlloc(memory, size);
  }

  static void OnMapMem(void* context, const void* memory, size_t size) {
    TestMemReporter* t = static_cast<TestMemReporter*>(context);
    t->ReportMapMem(memory, size);
  }

  static void OnDealloc(void* context, const void* memory) {
    TestMemReporter* t = static_cast<TestMemReporter*>(context);
    t->ReportDealloc(memory);
  }

  static void SbUnMapMem(void* context, const void* memory, size_t size) {
    TestMemReporter* t = static_cast<TestMemReporter*>(context);
    t->ReportUnMapMemory(memory, size);
  }

  static SbMemoryReporter CreateSbMemoryReporter(TestMemReporter* context) {
    SbMemoryReporter cb = {OnMalloc, OnDealloc, OnMapMem, SbUnMapMem, context};
    return cb;
  }

  void ReportAlloc(const void* memory, size_t size) {
    if (!GetMemoryTrackingEnabled_ThreadLocal()) {
      return;
    }
    starboard::ScopedLock lock(mutex_);
    last_allocation_ = memory;
    number_allocs_++;
  }

  void ReportMapMem(const void* memory, size_t size) {
    if (!GetMemoryTrackingEnabled_ThreadLocal()) {
      return;
    }
    starboard::ScopedLock lock(mutex_);
    last_mem_map_ = memory;
    number_map_mem_++;
  }

  void ReportDealloc(const void* memory) {
    if (!GetMemoryTrackingEnabled_ThreadLocal()) {
      return;
    }
    starboard::ScopedLock lock(mutex_);
    last_deallocation_ = memory;
    number_allocs_--;
  }

  void ReportUnMapMemory(const void* memory, size_t size) {
    if (!GetMemoryTrackingEnabled_ThreadLocal()) {
      return;
    }
    starboard::ScopedLock lock(mutex_);
    last_mem_unmap_ = memory;
    number_map_mem_--;
  }

  void Construct() {
    Clear();
    memory_reporter_ = CreateSbMemoryReporter(this);
  }

  SbMemoryReporter memory_reporter_;
  starboard::Mutex mutex_;
  const void* last_allocation_;
  const void* last_deallocation_;
  const void* last_mem_map_;
  const void* last_mem_unmap_;
  int number_allocs_;
  int number_map_mem_;
};

///////////////////////////////////////////////////////////////////////////////
// Needed by all tests that require a memory tracker to be installed. On the
// first test the test memory tracker is installed and then after the last test
// the memory tracker is removed.
class MemoryReportingTest : public ::testing::Test {
 public:
  TestMemReporter* mem_reporter() { return s_test_alloc_tracker_; }
  bool MemoryReportingEnabled() const {
    return s_memory_reporter_error_enabled_;
  }

 protected:
  // Global setup - runs before the first test in the series.
  static void SetUpTestCase() {
    InitMemoryTrackingState_ThreadLocal();
    // global init test code should run here.
    if (s_test_alloc_tracker_ == NULL) {
      s_test_alloc_tracker_ = new TestMemReporter;
    }
    s_memory_reporter_error_enabled_ =
        SbMemorySetReporter(s_test_alloc_tracker_->memory_reporter());
  }

  // Global Teardown after last test has run it's course.
  static void TearDownTestCase() { s_test_alloc_tracker_->RemoveGlobalHooks(); }

  // Per test setup.
  virtual void SetUp() {
    mem_reporter()->Clear();
    // Allows current thread to capture memory allocations. If this wasn't
    // done then background threads spawned by a framework could notify this
    // class about allocations and fail the test.
    SetMemoryTrackingEnabled_ThreadLocal(true);
  }

  // Per test teardown.
  virtual void TearDown() {
    SetMemoryTrackingEnabled_ThreadLocal(false);
    if ((mem_reporter()->number_allocs() != 0) ||
        (mem_reporter()->number_map_mem() != 0)) {
      ADD_FAILURE_AT(__FILE__, __LINE__) << "Memory Leak detected.";
    }
    mem_reporter()->Clear();
  }
  static TestMemReporter* s_test_alloc_tracker_;
  static bool s_memory_reporter_error_enabled_;
};
TestMemReporter* MemoryReportingTest::s_test_alloc_tracker_ = NULL;
bool MemoryReportingTest::s_memory_reporter_error_enabled_ = false;

///////////////////////////////////////////////////////////////////////////////
// TESTS.
// There are two sets of tests: POSITIVE and NEGATIVE.
//  The positive tests are active when STARBOARD_ALLOWS_MEMORY_TRACKING is
//  defined and test that memory tracking is enabled.
//  NEGATIVE tests ensure that tracking is disabled when
//  STARBOARD_ALLOWS_MEMORY_TRACKING is not defined.
// When adding new tests:
//  POSITIVE tests are named normally.
//  NEGATIVE tets are named with "No" prefixed to the beginning.
//  Example:
//   TEST_F(MemoryReportingTest, CapturesAllocDealloc) <--- POSITIVE test.
//   TEST_F(MemoryReportingTest, NoCapturesAllocDealloc) <- NEGATIVE test.
//  All positive & negative tests are grouped together.
///////////////////////////////////////////////////////////////////////////////

#ifdef STARBOARD_ALLOWS_MEMORY_TRACKING
// These are POSITIVE tests, which test the expectation that when the define
// STARBOARD_ALLOWS_MEMORY_TRACKING is active that the memory tracker will
// receive memory allocations notifications.
//
// Tests the assumption that the SbMemoryAllocate and SbMemoryDeallocate
// will report memory allocations.
TEST_F(MemoryReportingTest, CapturesAllocDealloc) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  void* memory = SbMemoryAllocate(4);
  EXPECT_EQ_NO_TRACKING(1, mem_reporter()->number_allocs());

  EXPECT_EQ_NO_TRACKING(memory, mem_reporter()->last_allocation());

  SbMemoryDeallocate(memory);
  EXPECT_EQ_NO_TRACKING(mem_reporter()->number_allocs(), 0);

  // Should equal the last allocation.
  EXPECT_EQ_NO_TRACKING(memory, mem_reporter()->last_deallocation());
}

// Tests the assumption that SbMemoryReallocate() will report a
// deallocation and an allocation to the memory tracker.
TEST_F(MemoryReportingTest, CapturesRealloc) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  void* prev_memory = SbMemoryAllocate(4);
  void* new_memory = SbMemoryReallocate(prev_memory, 8);

  EXPECT_EQ_NO_TRACKING(new_memory, mem_reporter()->last_allocation());
  EXPECT_EQ_NO_TRACKING(prev_memory, mem_reporter()->last_deallocation());

  EXPECT_EQ_NO_TRACKING(1, mem_reporter()->number_allocs());

  SbMemoryDeallocate(new_memory);
  EXPECT_EQ_NO_TRACKING(mem_reporter()->number_allocs(), 0);
}

// Tests the assumption that the SbMemoryMap and SbMemoryUnmap
// will report memory allocations.
TEST_F(MemoryReportingTest, CapturesMemMapUnmap) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  const int64_t kMemSize = 4096;
  const int kFlags = kSbMemoryMapProtectReadWrite;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_map_mem());
  void* mem_chunk = SbMemoryMap(kMemSize, kFlags, "TestMemMap");
  EXPECT_EQ_NO_TRACKING(1, mem_reporter()->number_map_mem());

  // Now unmap the memory and confirm that this memory was reported as free.
  EXPECT_EQ_NO_TRACKING(mem_chunk, mem_reporter()->last_mem_map());
  SbMemoryUnmap(mem_chunk, kMemSize);
  EXPECT_EQ_NO_TRACKING(mem_chunk, mem_reporter()->last_mem_unmap());
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_map_mem());
  // On some platforms, bookkeeping for memory mapping can cost allocations.
  // Call Clear() explicitly before TearDown() checks number_allocs_;
  mem_reporter()->Clear();
}

// Tests the assumption that the operator new/delete will report
// memory allocations.
TEST_F(MemoryReportingTest, CapturesOperatorNewDelete) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  EXPECT_TRUE_NO_TRACKING(mem_reporter()->number_allocs() == 0);
  int* my_int = new int();
  EXPECT_TRUE_NO_TRACKING(mem_reporter()->number_allocs() == 1);

  bool is_last_allocation = my_int == mem_reporter()->last_allocation();

  EXPECT_TRUE_NO_TRACKING(is_last_allocation);

  delete my_int;
  EXPECT_TRUE_NO_TRACKING(mem_reporter()->number_allocs() == 0);

  // Expect last deallocation to be the expected pointer.
  EXPECT_EQ_NO_TRACKING(my_int, mem_reporter()->last_deallocation());
}

// Tests the assumption that the nothrow version of operator new will report
// memory allocations.
TEST_F(MemoryReportingTest, CapturesOperatorNewNothrow) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  int* my_int = new (std::nothrow) int();
  EXPECT_EQ_NO_TRACKING(1, mem_reporter()->number_allocs());

  bool is_last_allocation = my_int == mem_reporter()->last_allocation();

  EXPECT_TRUE_NO_TRACKING(is_last_allocation);

  delete my_int;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());

  // Expect last deallocation to be the expected pointer.
  EXPECT_EQ_NO_TRACKING(my_int, mem_reporter()->last_deallocation());
}

// Tests the assumption that the nothrow version of operator delete will report
// memory deallocations.
TEST_F(MemoryReportingTest, CapturesOperatorDeleteNothrow) {
  if (!MemoryReportingEnabled()) {
    SbLog(kSbLogPriorityInfo, "Memory reporting is disabled.\n");
    return;
  }
  const void* init_alloc = mem_reporter()->last_allocation();

  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  void* my_obj = nullptr;
  bool caught_exception = false;
  try {
    my_obj = new (std::nothrow) ThrowConstructor();
  } catch (std::exception e) {
    caught_exception = true;
  }
  EXPECT_TRUE(caught_exception);
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());

  // Expect that an allocation occurred, even though we never got a pointer.
  EXPECT_EQ_NO_TRACKING(nullptr, my_obj);
  EXPECT_NE_NO_TRACKING(nullptr, mem_reporter()->last_allocation());
  EXPECT_NE_NO_TRACKING(init_alloc, mem_reporter()->last_allocation());

  // Expect last deallocation to be the allocation we never got.
  EXPECT_EQ_NO_TRACKING(mem_reporter()->last_allocation(),
                        mem_reporter()->last_deallocation());
}

#else  // !defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
// These are NEGATIVE tests, which test the expectation that when the
// STARBOARD_ALLOWS_MEMORY_TRACKING is undefined that the memory tracker does
// not receive memory allocations notifications.

TEST_F(MemoryReportingTest, NoCapturesAllocDealloc) {
  EXPECT_FALSE_NO_TRACKING(MemoryReportingEnabled());

  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  void* memory = SbMemoryAllocate(4);
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_allocation());

  SbMemoryDeallocate(memory);
  EXPECT_EQ_NO_TRACKING(mem_reporter()->number_allocs(), 0);
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_deallocation());
}

TEST_F(MemoryReportingTest, NoCapturesRealloc) {
  EXPECT_FALSE_NO_TRACKING(MemoryReportingEnabled());
  void* prev_memory = SbMemoryAllocate(4);
  void* new_memory = SbMemoryReallocate(prev_memory, 8);

  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_allocation());
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_deallocation());
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());

  SbMemoryDeallocate(new_memory);
  EXPECT_EQ_NO_TRACKING(mem_reporter()->number_allocs(), 0);
}

TEST_F(MemoryReportingTest, NoCapturesMemMapUnmap) {
  EXPECT_FALSE_NO_TRACKING(MemoryReportingEnabled());
  const int64_t kMemSize = 4096;
  const int kFlags = 0;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  void* mem_chunk = SbMemoryMap(kMemSize, kFlags, "TestMemMap");
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());

  // Now unmap the memory and confirm that this memory was reported as free.
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_mem_map());
  SbMemoryUnmap(mem_chunk, kMemSize);
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_mem_unmap());
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
}

TEST_F(MemoryReportingTest, NoCapturesOperatorNewDelete) {
  EXPECT_FALSE_NO_TRACKING(MemoryReportingEnabled());
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_map_mem());
  int* my_int = new int();
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_map_mem());
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_allocation());

  delete my_int;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_map_mem());
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_deallocation());
}

#endif  // !defined(STARBOARD_ALLOWS_MEMORY_TRACKING)

/////////////////////////////// Implementation ////////////////////////////////

// Simple ThreadLocalBool class which allows a default value to be
// true or false.
class ThreadLocalBool {
 public:
  ThreadLocalBool() {
    // NULL is the destructor.
    slot_ = SbThreadCreateLocalKey(NULL);
  }

  ~ThreadLocalBool() { SbThreadDestroyLocalKey(slot_); }

  void SetEnabled(bool value) { SetEnabledThreadLocal(value); }

  bool Enabled() const { return GetEnabledThreadLocal(); }

 private:
  void SetEnabledThreadLocal(bool value) {
    void* bool_as_pointer;
    if (value) {
      bool_as_pointer = reinterpret_cast<void*>(0x1);
    } else {
      bool_as_pointer = NULL;
    }
    SbThreadSetLocalValue(slot_, bool_as_pointer);
  }

  bool GetEnabledThreadLocal() const {
    void* ptr = SbThreadGetLocalValue(slot_);
    return ptr != NULL;
  }

  mutable SbThreadLocalKey slot_;
  bool default_value_;
};

void InitMemoryTrackingState_ThreadLocal() {
  GetMemoryTrackingEnabled_ThreadLocal();
}

static ThreadLocalBool* GetMemoryTrackingState() {
  static ThreadLocalBool* thread_local_bool = new ThreadLocalBool();
  return thread_local_bool;
}

bool GetMemoryTrackingEnabled_ThreadLocal() {
  return GetMemoryTrackingState()->Enabled();
}

void SetMemoryTrackingEnabled_ThreadLocal(bool value) {
  GetMemoryTrackingState()->SetEnabled(value);
}

// No use for these macros anymore.
#undef EXPECT_EQ_NO_TRACKING
#undef EXPECT_TRUE_NO_TRACKING
#undef EXPECT_FALSE_NO_TRACKING
#undef ASSERT_EQ_NO_TRACKING
#undef ASSERT_TRUE_NO_TRACKING
#undef ASSERT_FALSE_NO_TRACKING

}  // namespace
}  // namespace nplb
}  // namespace starboard
