// Copyright 2019 The Abseil Authors
//
// 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
//
//      https://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 "absl/strings/internal/cordz_info.h"

#include <vector>

#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
#include "absl/strings/cordz_test_helpers.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/strings/str_cat.h"
#include "absl/types/span.h"

namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
namespace {

using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::HasSubstr;
using ::testing::Ne;
using ::testing::SizeIs;

// Used test values
auto constexpr kUnknownMethod = CordzUpdateTracker::kUnknown;
auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString;
auto constexpr kChildMethod = CordzUpdateTracker::kConstructorCord;
auto constexpr kUpdateMethod = CordzUpdateTracker::kAppendString;

// Local less verbose helper
std::vector<const CordzHandle*> DeleteQueue() {
  return CordzHandle::DiagnosticsGetDeleteQueue();
}

std::string FormatStack(absl::Span<void* const> raw_stack) {
  static constexpr size_t buf_size = 1 << 14;
  std::unique_ptr<char[]> buf(new char[buf_size]);
  std::string output;
  for (void* stackp : raw_stack) {
    if (absl::Symbolize(stackp, buf.get(), buf_size)) {
      absl::StrAppend(&output, "    ", buf.get(), "\n");
    }
  }
  return output;
}

TEST(CordzInfoTest, TrackCord) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();
  ASSERT_THAT(info, Ne(nullptr));
  EXPECT_FALSE(info->is_snapshot());
  EXPECT_THAT(CordzInfo::Head(CordzSnapshot()), Eq(info));
  EXPECT_THAT(info->GetCordRepForTesting(), Eq(data.rep.rep));
  info->Untrack();
}

TEST(CordzInfoTest, MaybeTrackChildCordWithoutSampling) {
  CordzSamplingIntervalHelper sample_none(99999);
  TestCordData parent, child;
  CordzInfo::MaybeTrackCord(child.data, parent.data, kTrackCordMethod);
  EXPECT_THAT(child.data.cordz_info(), Eq(nullptr));
}

TEST(CordzInfoTest, MaybeTrackChildCordWithSampling) {
  CordzSamplingIntervalHelper sample_all(1);
  TestCordData parent, child;
  CordzInfo::MaybeTrackCord(child.data, parent.data, kTrackCordMethod);
  EXPECT_THAT(child.data.cordz_info(), Eq(nullptr));
}

TEST(CordzInfoTest, MaybeTrackChildCordWithoutSamplingParentSampled) {
  CordzSamplingIntervalHelper sample_none(99999);
  TestCordData parent, child;
  CordzInfo::TrackCord(parent.data, kTrackCordMethod);
  CordzInfo::MaybeTrackCord(child.data, parent.data, kTrackCordMethod);
  CordzInfo* parent_info = parent.data.cordz_info();
  CordzInfo* child_info = child.data.cordz_info();
  ASSERT_THAT(child_info, Ne(nullptr));
  EXPECT_THAT(child_info->GetCordRepForTesting(), Eq(child.rep.rep));
  EXPECT_THAT(child_info->GetParentStack(), parent_info->GetStack());
  parent_info->Untrack();
  child_info->Untrack();
}

TEST(CordzInfoTest, MaybeTrackChildCordWithoutSamplingChildSampled) {
  CordzSamplingIntervalHelper sample_none(99999);
  TestCordData parent, child;
  CordzInfo::TrackCord(child.data, kTrackCordMethod);
  CordzInfo::MaybeTrackCord(child.data, parent.data, kTrackCordMethod);
  EXPECT_THAT(child.data.cordz_info(), Eq(nullptr));
}

TEST(CordzInfoTest, MaybeTrackChildCordWithSamplingChildSampled) {
  CordzSamplingIntervalHelper sample_all(1);
  TestCordData parent, child;
  CordzInfo::TrackCord(child.data, kTrackCordMethod);
  CordzInfo::MaybeTrackCord(child.data, parent.data, kTrackCordMethod);
  EXPECT_THAT(child.data.cordz_info(), Eq(nullptr));
}

TEST(CordzInfoTest, UntrackCord) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();

  info->Untrack();
  EXPECT_THAT(DeleteQueue(), SizeIs(0u));
}

TEST(CordzInfoTest, UntrackCordWithSnapshot) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();

  CordzSnapshot snapshot;
  info->Untrack();
  EXPECT_THAT(CordzInfo::Head(CordzSnapshot()), Eq(nullptr));
  EXPECT_THAT(info->GetCordRepForTesting(), Eq(data.rep.rep));
  EXPECT_THAT(DeleteQueue(), ElementsAre(info, &snapshot));
}

TEST(CordzInfoTest, SetCordRep) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();

  TestCordRep rep;
  info->Lock(CordzUpdateTracker::kAppendCord);
  info->SetCordRep(rep.rep);
  info->Unlock();
  EXPECT_THAT(info->GetCordRepForTesting(), Eq(rep.rep));

  info->Untrack();
}

TEST(CordzInfoTest, SetCordRepNullUntracksCordOnUnlock) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();

  info->Lock(CordzUpdateTracker::kAppendString);
  info->SetCordRep(nullptr);
  EXPECT_THAT(info->GetCordRepForTesting(), Eq(nullptr));
  EXPECT_THAT(CordzInfo::Head(CordzSnapshot()), Eq(info));

  info->Unlock();
  EXPECT_THAT(CordzInfo::Head(CordzSnapshot()), Eq(nullptr));
}

TEST(CordzInfoTest, RefCordRep) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();

  size_t refcount = data.rep.rep->refcount.Get();
  EXPECT_THAT(info->RefCordRep(), Eq(data.rep.rep));
  EXPECT_THAT(data.rep.rep->refcount.Get(), Eq(refcount + 1));
  CordRep::Unref(data.rep.rep);
  info->Untrack();
}

#if GTEST_HAS_DEATH_TEST

TEST(CordzInfoTest, SetCordRepRequiresMutex) {
  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();
  TestCordRep rep;
  EXPECT_DEBUG_DEATH(info->SetCordRep(rep.rep), ".*");
  info->Untrack();
}

#endif  // GTEST_HAS_DEATH_TEST

TEST(CordzInfoTest, TrackUntrackHeadFirstV2) {
  CordzSnapshot snapshot;
  EXPECT_THAT(CordzInfo::Head(snapshot), Eq(nullptr));

  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info1 = data.data.cordz_info();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info1));
  EXPECT_THAT(info1->Next(snapshot), Eq(nullptr));

  TestCordData data2;
  CordzInfo::TrackCord(data2.data, kTrackCordMethod);
  CordzInfo* info2 = data2.data.cordz_info();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info2));
  EXPECT_THAT(info2->Next(snapshot), Eq(info1));
  EXPECT_THAT(info1->Next(snapshot), Eq(nullptr));

  info2->Untrack();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info1));
  EXPECT_THAT(info1->Next(snapshot), Eq(nullptr));

  info1->Untrack();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(nullptr));
}

TEST(CordzInfoTest, TrackUntrackTailFirstV2) {
  CordzSnapshot snapshot;
  EXPECT_THAT(CordzInfo::Head(snapshot), Eq(nullptr));

  TestCordData data;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info1 = data.data.cordz_info();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info1));
  EXPECT_THAT(info1->Next(snapshot), Eq(nullptr));

  TestCordData data2;
  CordzInfo::TrackCord(data2.data, kTrackCordMethod);
  CordzInfo* info2 = data2.data.cordz_info();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info2));
  EXPECT_THAT(info2->Next(snapshot), Eq(info1));
  EXPECT_THAT(info1->Next(snapshot), Eq(nullptr));

  info1->Untrack();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(info2));
  EXPECT_THAT(info2->Next(snapshot), Eq(nullptr));

  info2->Untrack();
  ASSERT_THAT(CordzInfo::Head(snapshot), Eq(nullptr));
}

TEST(CordzInfoTest, StackV2) {
  TestCordData data;
  // kMaxStackDepth is intentionally less than 64 (which is the max depth that
  // Cordz will record) because if the actual stack depth is over 64
  // (which it is on Apple platforms) then the expected_stack will end up
  // catching a few frames at the end that the actual_stack didn't get and
  // it will no longer be subset. At the time of this writing 58 is the max
  // that will allow this test to pass (with a minimum os version of iOS 9), so
  // rounded down to 50 to hopefully not run into this in the future if Apple
  // makes small modifications to its testing stack. 50 is sufficient to prove
  // that we got a decent stack.
  static constexpr int kMaxStackDepth = 50;
  CordzInfo::TrackCord(data.data, kTrackCordMethod);
  CordzInfo* info = data.data.cordz_info();
  std::vector<void*> local_stack;
  local_stack.resize(kMaxStackDepth);
  // In some environments we don't get stack traces. For example in Android
  // absl::GetStackTrace will return 0 indicating it didn't find any stack. The
  // resultant formatted stack will be "", but that still equals the stack
  // recorded in CordzInfo, which is also empty. The skip_count is 1 so that the
  // line number of the current stack isn't included in the HasSubstr check.
  local_stack.resize(static_cast<size_t>(
      absl::GetStackTrace(local_stack.data(), kMaxStackDepth,
                          /*skip_count=*/1)));

  std::string got_stack = FormatStack(info->GetStack());
  std::string expected_stack = FormatStack(local_stack);
  // If TrackCord is inlined, got_stack should match expected_stack. If it isn't
  // inlined, got_stack should include an additional frame not present in
  // expected_stack. Either way, expected_stack should be a substring of
  // got_stack.
  EXPECT_THAT(got_stack, HasSubstr(expected_stack));

  info->Untrack();
}

// Local helper functions to get different stacks for child and parent.
CordzInfo* TrackChildCord(InlineData& data, const InlineData& parent) {
  CordzInfo::TrackCord(data, parent, kChildMethod);
  return data.cordz_info();
}
CordzInfo* TrackParentCord(InlineData& data) {
  CordzInfo::TrackCord(data, kTrackCordMethod);
  return data.cordz_info();
}

TEST(CordzInfoTest, GetStatistics) {
  TestCordData data;
  CordzInfo* info = TrackParentCord(data.data);

  CordzStatistics statistics = info->GetCordzStatistics();
  EXPECT_THAT(statistics.size, Eq(data.rep.rep->length));
  EXPECT_THAT(statistics.method, Eq(kTrackCordMethod));
  EXPECT_THAT(statistics.parent_method, Eq(kUnknownMethod));
  EXPECT_THAT(statistics.update_tracker.Value(kTrackCordMethod), Eq(1));

  info->Untrack();
}

TEST(CordzInfoTest, LockCountsMethod) {
  TestCordData data;
  CordzInfo* info = TrackParentCord(data.data);

  info->Lock(kUpdateMethod);
  info->Unlock();
  info->Lock(kUpdateMethod);
  info->Unlock();

  CordzStatistics statistics = info->GetCordzStatistics();
  EXPECT_THAT(statistics.update_tracker.Value(kUpdateMethod), Eq(2));

  info->Untrack();
}

TEST(CordzInfoTest, FromParent) {
  TestCordData parent;
  TestCordData child;
  CordzInfo* info_parent = TrackParentCord(parent.data);
  CordzInfo* info_child = TrackChildCord(child.data, parent.data);

  std::string stack = FormatStack(info_parent->GetStack());
  std::string parent_stack = FormatStack(info_child->GetParentStack());
  EXPECT_THAT(stack, Eq(parent_stack));

  CordzStatistics statistics = info_child->GetCordzStatistics();
  EXPECT_THAT(statistics.size, Eq(child.rep.rep->length));
  EXPECT_THAT(statistics.method, Eq(kChildMethod));
  EXPECT_THAT(statistics.parent_method, Eq(kTrackCordMethod));
  EXPECT_THAT(statistics.update_tracker.Value(kChildMethod), Eq(1));

  info_parent->Untrack();
  info_child->Untrack();
}

}  // namespace
}  // namespace cord_internal
ABSL_NAMESPACE_END
}  // namespace absl
