// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <string.h>

#include <memory>

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/synchronization/lock.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/thread.h"
#include "base/trace_event/category_registry.h"
#include "base/trace_event/trace_category.h"
#include "build/build_config.h"
#include "starboard/types.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace base {
namespace trace_event {

// Static initializers are generally forbidden. However, in the past we ran in
// the case of some test using tracing in a static initializer. This test checks
// That the category registry doesn't rely on static initializers itself and is
// functional even if called from another static initializer.
bool Initializer() {
  return CategoryRegistry::kCategoryMetadata &&
         CategoryRegistry::kCategoryMetadata->is_valid();
}
bool g_initializer_check = Initializer();

class TraceCategoryTest : public testing::Test {
 public:
  void SetUp() override { CategoryRegistry::Initialize(); }

  void TearDown() override { CategoryRegistry::ResetForTesting(); }

  static bool GetOrCreateCategoryByName(const char* name, TraceCategory** cat) {
    static LazyInstance<Lock>::Leaky g_lock = LAZY_INSTANCE_INITIALIZER;
    bool is_new_cat = false;
    *cat = CategoryRegistry::GetCategoryByName(name);
    if (!*cat) {
      AutoLock lock(g_lock.Get());
      is_new_cat = CategoryRegistry::GetOrCreateCategoryLocked(
          name, [](TraceCategory*) {}, cat);
    }
    return is_new_cat;
  };

  static CategoryRegistry::Range GetAllCategories() {
    return CategoryRegistry::GetAllCategories();
  }

  static void TestRaceThreadMain(WaitableEvent* event) {
    TraceCategory* cat = nullptr;
    event->Wait();
    GetOrCreateCategoryByName("__test_race", &cat);
    EXPECT_NE(nullptr, cat);
  }
};

TEST_F(TraceCategoryTest, Basic) {
  ASSERT_NE(nullptr, CategoryRegistry::kCategoryMetadata);
  ASSERT_TRUE(CategoryRegistry::kCategoryMetadata->is_valid());
  ASSERT_FALSE(CategoryRegistry::kCategoryMetadata->is_enabled());

  // Metadata category is built-in and should create a new category.
  TraceCategory* cat_meta = nullptr;
  const char* kMetadataName = CategoryRegistry::kCategoryMetadata->name();
  ASSERT_FALSE(GetOrCreateCategoryByName(kMetadataName, &cat_meta));
  ASSERT_EQ(CategoryRegistry::kCategoryMetadata, cat_meta);

  TraceCategory* cat_1 = nullptr;
  ASSERT_TRUE(GetOrCreateCategoryByName("__test_basic_ab", &cat_1));
  ASSERT_FALSE(cat_1->is_enabled());
  ASSERT_EQ(0u, cat_1->enabled_filters());
  cat_1->set_state_flag(TraceCategory::ENABLED_FOR_RECORDING);
  cat_1->set_state_flag(TraceCategory::ENABLED_FOR_FILTERING);
  ASSERT_EQ(TraceCategory::ENABLED_FOR_RECORDING |
                TraceCategory::ENABLED_FOR_FILTERING,
            cat_1->state());

  cat_1->set_enabled_filters(129);
  ASSERT_EQ(129u, cat_1->enabled_filters());
  ASSERT_EQ(cat_1, CategoryRegistry::GetCategoryByStatePtr(cat_1->state_ptr()));

  cat_1->clear_state_flag(TraceCategory::ENABLED_FOR_FILTERING);
  ASSERT_EQ(TraceCategory::ENABLED_FOR_RECORDING, cat_1->state());
  ASSERT_EQ(TraceCategory::ENABLED_FOR_RECORDING, *cat_1->state_ptr());
  ASSERT_TRUE(cat_1->is_enabled());

  TraceCategory* cat_2 = nullptr;
  ASSERT_TRUE(GetOrCreateCategoryByName("__test_basic_a", &cat_2));
  ASSERT_FALSE(cat_2->is_enabled());
  cat_2->set_state_flag(TraceCategory::ENABLED_FOR_RECORDING);

  TraceCategory* cat_2_copy = nullptr;
  ASSERT_FALSE(GetOrCreateCategoryByName("__test_basic_a", &cat_2_copy));
  ASSERT_EQ(cat_2, cat_2_copy);

  TraceCategory* cat_3 = nullptr;
  ASSERT_TRUE(
      GetOrCreateCategoryByName("__test_basic_ab,__test_basic_a", &cat_3));
  ASSERT_FALSE(cat_3->is_enabled());
  ASSERT_EQ(0u, cat_3->enabled_filters());

  int num_test_categories_seen = 0;
  for (const TraceCategory& cat : GetAllCategories()) {
    if (strcmp(cat.name(), kMetadataName) == 0)
      ASSERT_TRUE(CategoryRegistry::IsBuiltinCategory(&cat));

    if (strncmp(cat.name(), "__test_basic_", 13) == 0) {
      ASSERT_FALSE(CategoryRegistry::IsBuiltinCategory(&cat));
      num_test_categories_seen++;
    }
  }
  ASSERT_EQ(3, num_test_categories_seen);
  ASSERT_TRUE(g_initializer_check);
}

// Tries to cover the case of multiple threads creating the same category
// simultaneously. Should never end up with distinct entries with the same name.
#if defined(OS_FUCHSIA)
// TODO(crbug.com/738275): This is flaky on Fuchsia.
#define MAYBE_ThreadRaces DISABLED_ThreadRaces
#else
#define MAYBE_ThreadRaces ThreadRaces
#endif
TEST_F(TraceCategoryTest, MAYBE_ThreadRaces) {
  const int kNumThreads = 32;
  std::unique_ptr<Thread> threads[kNumThreads];
  for (int i = 0; i < kNumThreads; i++) {
    threads[i].reset(new Thread("test thread"));
    threads[i]->Start();
  }
  WaitableEvent sync_event(WaitableEvent::ResetPolicy::MANUAL,
                           WaitableEvent::InitialState::NOT_SIGNALED);
  for (int i = 0; i < kNumThreads; i++) {
    threads[i]->task_runner()->PostTask(
        FROM_HERE, BindOnce(&TestRaceThreadMain, Unretained(&sync_event)));
  }
  sync_event.Signal();
  for (int i = 0; i < kNumThreads; i++)
    threads[i]->Stop();

  int num_times_seen = 0;
  for (const TraceCategory& cat : GetAllCategories()) {
    if (strcmp(cat.name(), "__test_race") == 0)
      num_times_seen++;
  }
  ASSERT_EQ(1, num_times_seen);
}

}  // namespace trace_event
}  // namespace base
