/*
 * Copyright 2016 Google Inc. 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 "nb/memory_scope.h"
#include "starboard/mutex.h"
#include "nb/thread_local_object.h"

#include "testing/gtest/include/gtest/gtest.h"

namespace nb {
namespace {

bool StarboardAllowsMemoryTracking() {
#if defined(STARBOARD_ALLOWS_MEMORY_TRACKING)
  return true;
#else
  return false;
#endif
}

// This is a memory scope reporter that is compatible
// with the MemoryScopeReporter.
class TestMemoryScopeReporter {
 public:
  typedef std::vector<NbMemoryScopeInfo*> MemoryScopeVector;

  TestMemoryScopeReporter() {
    memory_scope_reporter_ = CreateMemoryScopeReporter();
  }

  NbMemoryScopeReporter* memory_scope_reporter() {
    return &memory_scope_reporter_;
  }

  MemoryScopeVector* stack_thread_local() { return stack_tlo_.GetOrCreate(); }

  void OnPushMemoryScope(NbMemoryScopeInfo* memory_scope) {
    stack_thread_local()->push_back(memory_scope);
  }

  void OnPopMemoryScope() {
    MemoryScopeVector* stack = stack_thread_local();
    if (!stack->empty()) {
      stack->pop_back();
    } else {
      ADD_FAILURE_AT(__FILE__, __LINE__)
          << " stack was empty and could not be popped.";
    }
  }

 private:
  static void OnPushMemoryScopeCallback(void* context,
                                        NbMemoryScopeInfo* info) {
    TestMemoryScopeReporter* t = static_cast<TestMemoryScopeReporter*>(context);
    t->OnPushMemoryScope(info);
  }

  static void OnPopMemoryScopeCallback(void* context) {
    TestMemoryScopeReporter* t = static_cast<TestMemoryScopeReporter*>(context);
    t->OnPopMemoryScope();
  }

  NbMemoryScopeReporter CreateMemoryScopeReporter() {
    NbMemoryScopeReporter reporter = {OnPushMemoryScopeCallback,
                                      OnPopMemoryScopeCallback, this};
    return reporter;
  }

  NbMemoryScopeReporter memory_scope_reporter_;
  ThreadLocalObject<MemoryScopeVector> stack_tlo_;
};

// A test framework for testing the Pushing & popping memory scopes.
// The key feature here is that reporter is setup on the first test
// instance and torn down after the last test has run.
class MemoryScopeReportingTest : public ::testing::Test {
 public:
  TestMemoryScopeReporter* test_memory_reporter() { return s_reporter_; }

  bool reporting_enabled() const { return s_reporter_enabled_; }

 protected:
  static void SetUpTestCase() {
    if (!s_reporter_) {
      s_reporter_ = new TestMemoryScopeReporter;
    }
    s_reporter_enabled_ =
        NbSetMemoryScopeReporter(s_reporter_->memory_scope_reporter());

    EXPECT_EQ(StarboardAllowsMemoryTracking(), s_reporter_enabled_)
        << "Expected the memory scope reporter to be enabled whenever "
           "starboard memory tracking is allowed.";
  }

  static void TearDownTestCase() {
    // The reporter itself is not deleted because other threads could
    // be traversing through it's data structures. It's better just to leave
    // the object alive for the purposes of this unit test and set the pointer
    // to NULL.
    // This is done in order to make the MemoryScopeReport object lock free.
    // This increases performance and reduces complexity of design.
    NbSetMemoryScopeReporter(NULL);
  }

  // Per test setup.
  virtual void SetUp() {
    test_memory_reporter()->stack_thread_local()->clear();
  }

  static TestMemoryScopeReporter* s_reporter_;
  static bool s_reporter_enabled_;
};
TestMemoryScopeReporter* MemoryScopeReportingTest::s_reporter_ = NULL;
bool MemoryScopeReportingTest::s_reporter_enabled_;

///////////////////////////////////////////////////////////////////////////////
// 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 tests are named with "No" prefixed to the beginning.
//  Example:
//   TEST_F(MemoryScopeReportingTest, PushPop) <--- POSITIVE test.
//   TEST_F(MemoryScopeReportingTest, NoPushPop) <- NEGATIVE test.
//  All positive & negative tests are grouped together.
///////////////////////////////////////////////////////////////////////////////

#if defined(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 scope reporter
// will receive memory scope notifications.

// Tests the assumption that the SbMemoryAllocate and SbMemoryDeallocate
// will report memory allocations.
TEST_F(MemoryScopeReportingTest, PushPop) {
  ASSERT_TRUE(reporting_enabled());
  const int line_number = __LINE__;
  const char* file_name = __FILE__;
  const char* function_name = __FUNCTION__;
  NbMemoryScopeInfo info = {0,              // Cached value (null).
                            "Javascript",   // Name of the memory scope.
                            file_name,      // Filename that invoked this.
                            line_number,    // Line number.
                            function_name,  // Function name.
                            true};          // true allows caching.

  NbPushMemoryScope(&info);

  ASSERT_FALSE(test_memory_reporter()->stack_thread_local()->empty());
  NbMemoryScopeInfo* info_ptr =
      test_memory_reporter()->stack_thread_local()->front();

  EXPECT_EQ(&info, info_ptr);
  EXPECT_STREQ(info.file_name_, file_name);
  EXPECT_STREQ(info.function_name_, function_name);
  EXPECT_EQ(info.line_number_, line_number);

  NbPopMemoryScope();
  EXPECT_TRUE(test_memory_reporter()->stack_thread_local()->empty());
}

// Tests the expectation that the memory reporting macros will
// push/pop memory regions and will also correctly bind to the
// file, linenumber and also the function name.
TEST_F(MemoryScopeReportingTest, Macros) {
  ASSERT_TRUE(reporting_enabled());
  // There should be no leftover stack objects.
  EXPECT_TRUE(test_memory_reporter()->stack_thread_local()->empty());
  {
    const int line_before = __LINE__;
    TRACK_MEMORY_SCOPE("TestMemoryScope");
    const int predicted_line = line_before + 1;

    NbMemoryScopeInfo* info_ptr =
        test_memory_reporter()->stack_thread_local()->front();

    // TRACK_MEMORY_SCOPE is defined to allow caching.
    EXPECT_EQ(true, info_ptr->allows_caching_);

    // The cached_handle_ is not mutated by TestMemoryScopeReporter so
    // therefore it should be the default value of 0.
    EXPECT_EQ(0, info_ptr->cached_handle_);

    EXPECT_STREQ("TestMemoryScope", info_ptr->memory_scope_name_);
    EXPECT_STREQ(__FILE__, info_ptr->file_name_);
    EXPECT_EQ(predicted_line, info_ptr->line_number_);
    EXPECT_STREQ(__FUNCTION__, info_ptr->function_name_);
  }
  // Expect that the stack object is now empty again.
  EXPECT_TRUE(test_memory_reporter()->stack_thread_local()->empty());
}

#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 scope reprter
// does not receive memory scope notifications.

// Tests the expectation that push pop does not send notifications to the
// reporter when disabled.
TEST_F(MemoryScopeReportingTest, NoPushPop) {
  ASSERT_FALSE(reporting_enabled());
  const int line_number = __LINE__;
  const char* file_name = __FILE__;
  const char* function_name = __FUNCTION__;
  NbMemoryScopeInfo info = {0,              // Cached value (null).
                            "Javascript",   // Name of the memory scope.
                            file_name,      // Filename that invoked this.
                            line_number,    // Line number.
                            function_name,  // Function name.
                            true};          // true allows caching.

  NbPushMemoryScope(&info);

  ASSERT_FALSE(test_memory_reporter()->stack_thread_local()->empty());
  NbMemoryScopeInfo* info_ptr =
      test_memory_reporter()->stack_thread_local()->front();

  EXPECT_EQ(&info, info_ptr);
  EXPECT_STREQ(info.file_name_, file_name);
  EXPECT_STREQ(info.function_name_, function_name);
  EXPECT_EQ(info.line_number_, line_number);

  NbPopMemoryScope();
  EXPECT_TRUE(test_memory_reporter()->stack_thread_local()->empty());
}

// Tests the expectation that the memory reporting macros are disabled when
// memory tracking is not allowed.
TEST_F(MemoryScopeReportingTest, NoMacros) {
  ASSERT_FALSE(reporting_enabled());
  // Test that the macros do nothing when memory reporting has been
  // disabled.
  TRACK_MEMORY_SCOPE("InternalMemoryRegion");
  ASSERT_TRUE(test_memory_reporter()->stack_thread_local()->empty())
      << "Memory reporting received notifications when it should be disabled.";
}
#endif

}  // namespace.
}  // namespace nb.
