// 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);
}

#if SB_HAS(MMAP)
// 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());
}
#endif  // SB_HAS(MMAP)

// 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
