// 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/configuration.h"
#include "starboard/memory.h"
#include "starboard/memory_reporter.h"
#include "starboard/mutex.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 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_; }

  void Clear() {
    starboard::ScopedLock lock(mutex_);
    number_allocs_ = 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_allocs_++;
  }

  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_allocs_--;
  }

  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_;
};

///////////////////////////////////////////////////////////////////////////////
// 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) {
      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()) {
    SB_DLOG(INFO) << "Memory reporting is disabled.";
    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()) {
    SB_DLOG(INFO) << "Memory reporting is disabled.";
    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()) {
    SB_DLOG(INFO) << "Memory reporting is disabled.";
    return;
  }
  const int64_t kMemSize = 4096;
  const int kFlags = kSbMemoryMapProtectReadWrite;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  void* mem_chunk = SbMemoryMap(kMemSize, kFlags, "TestMemMap");
  EXPECT_EQ_NO_TRACKING(1, mem_reporter()->number_allocs());

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

// Tests the assumption that the operator/delete will report
// memory allocations.
TEST_F(MemoryReportingTest, CapturesOperatorNewDelete) {
  if (!MemoryReportingEnabled()) {
    SB_DLOG(INFO) << "Memory reporting is disabled.";
    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());
}

#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_allocs());
  int* my_int = new int();
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  EXPECT_EQ_NO_TRACKING(NULL, mem_reporter()->last_allocation());

  delete my_int;
  EXPECT_EQ_NO_TRACKING(0, mem_reporter()->number_allocs());
  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
