/*
 * Copyright (C) 2019 The Android Open Source Project
 *
 * 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 "src/trace_processor/importers/proto/heap_profile_tracker.h"

#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
#include "src/trace_processor/types/trace_processor_context.h"
#include "test/gtest_and_gmock.h"

namespace perfetto {
namespace trace_processor {
namespace {

struct Packet {
  uint32_t mapping_name_id;
  uint32_t build_id;
  uint32_t frame_name_id;
  uint32_t mapping_id;
  uint32_t frame_id;
};

constexpr Packet kFirstPacket{1, 2, 3, 1, 1};
constexpr Packet kSecondPacket{3, 2, 1, 2, 2};

constexpr auto kMappingExactOffset = 123;
constexpr auto kMappingStartOffset = 1231;
constexpr auto kMappingStart = 234;
constexpr auto kMappingEnd = 345;
constexpr auto kMappingLoadBias = 456;
constexpr auto kDefaultSequence = 1;

// heapprofd on Android Q has large callstack ideas, explicitly test large
// values.
constexpr auto kCallstackId = 1ull << 34;

static constexpr auto kFrameRelPc = 567;
static constexpr char kBuildIDName[] = "[build id]";
static constexpr char kBuildIDHexName[] = "5b6275696c642069645d";

using ::testing::ElementsAre;

class HeapProfileTrackerDupTest : public ::testing::Test {
 public:
  HeapProfileTrackerDupTest() {
    context.storage.reset(new TraceStorage());
    context.global_stack_profile_tracker.reset(new GlobalStackProfileTracker());
    sequence_stack_profile_tracker.reset(
        new SequenceStackProfileTracker(&context));
    context.heap_profile_tracker.reset(new HeapProfileTracker(&context));

    mapping_name = context.storage->InternString("[mapping]");
    fully_qualified_mapping_name = context.storage->InternString("/[mapping]");
    build = context.storage->InternString(kBuildIDName);
    frame_name = context.storage->InternString("[frame]");
  }

 protected:
  void InsertMapping(const Packet& packet) {
    sequence_stack_profile_tracker->AddString(packet.mapping_name_id,
                                              "[mapping]");

    sequence_stack_profile_tracker->AddString(packet.build_id, kBuildIDName);

    SequenceStackProfileTracker::SourceMapping first_frame;
    first_frame.build_id = packet.build_id;
    first_frame.exact_offset = kMappingExactOffset;
    first_frame.start_offset = kMappingStartOffset;
    first_frame.start = kMappingStart;
    first_frame.end = kMappingEnd;
    first_frame.load_bias = kMappingLoadBias;
    first_frame.name_ids = {packet.mapping_name_id};

    sequence_stack_profile_tracker->AddMapping(packet.mapping_id, first_frame);
  }

  void InsertFrame(const Packet& packet) {
    InsertMapping(packet);
    sequence_stack_profile_tracker->AddString(packet.frame_name_id, "[frame]");

    SequenceStackProfileTracker::SourceFrame first_frame;
    first_frame.name_id = packet.frame_name_id;
    first_frame.mapping_id = packet.mapping_id;
    first_frame.rel_pc = kFrameRelPc;

    sequence_stack_profile_tracker->AddFrame(packet.frame_id, first_frame);
  }

  void InsertCallsite(const Packet& packet) {
    InsertFrame(packet);

    SequenceStackProfileTracker::SourceCallstack first_callsite = {
        packet.frame_id, packet.frame_id};
    sequence_stack_profile_tracker->AddCallstack(kCallstackId, first_callsite);
  }

  StringId mapping_name;
  StringId fully_qualified_mapping_name;
  StringId build;
  StringId frame_name;
  TraceProcessorContext context;
  std::unique_ptr<SequenceStackProfileTracker> sequence_stack_profile_tracker;
};

// Insert the same mapping from two different packets, with different strings
// interned, and assert we only store one.
TEST_F(HeapProfileTrackerDupTest, Mapping) {
  InsertMapping(kFirstPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);
  InsertMapping(kSecondPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);

  EXPECT_THAT(context.storage->stack_profile_mapping_table().build_id()[0],
              context.storage->InternString({kBuildIDHexName}));
  EXPECT_THAT(context.storage->stack_profile_mapping_table().exact_offset()[0],
              kMappingExactOffset);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().start_offset()[0],
              kMappingStartOffset);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().start()[0],
              kMappingStart);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().end()[0],
              kMappingEnd);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().load_bias()[0],
              kMappingLoadBias);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().name()[0],
              fully_qualified_mapping_name);
}

// Insert the same mapping from two different packets, with different strings
// interned, and assert we only store one.
TEST_F(HeapProfileTrackerDupTest, Frame) {
  InsertFrame(kFirstPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);
  InsertFrame(kSecondPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);

  const auto& frames = context.storage->stack_profile_frame_table();
  EXPECT_THAT(frames.name()[0], frame_name);
  EXPECT_THAT(frames.mapping()[0], MappingId{0});
  EXPECT_THAT(frames.rel_pc()[0], kFrameRelPc);
}

// Insert the same callstack from two different packets, assert it is only
// stored once.
TEST_F(HeapProfileTrackerDupTest, Callstack) {
  InsertCallsite(kFirstPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);
  InsertCallsite(kSecondPacket);
  context.heap_profile_tracker->FinalizeProfile(
      kDefaultSequence, sequence_stack_profile_tracker.get(), nullptr);

  const auto& callsite_table = context.storage->stack_profile_callsite_table();
  const auto& depth = callsite_table.depth();
  const auto& parent_id = callsite_table.parent_id();
  const auto& frame_id = callsite_table.frame_id();

  EXPECT_EQ(depth[0], 0u);
  EXPECT_EQ(depth[1], 1u);

  EXPECT_EQ(parent_id[0], std::nullopt);
  EXPECT_EQ(parent_id[1], CallsiteId{0});

  EXPECT_EQ(frame_id[0], FrameId{0});
  EXPECT_EQ(frame_id[1], FrameId{0});
}

std::optional<CallsiteId> FindCallstack(const TraceStorage& storage,
                                        int64_t depth,
                                        std::optional<CallsiteId> parent,
                                        FrameId frame_id) {
  const auto& callsites = storage.stack_profile_callsite_table();
  for (uint32_t i = 0; i < callsites.row_count(); ++i) {
    if (callsites.depth()[i] == depth && callsites.parent_id()[i] == parent &&
        callsites.frame_id()[i] == frame_id) {
      return callsites.id()[i];
    }
  }
  return std::nullopt;
}

TEST(HeapProfileTrackerTest, SourceMappingPath) {
  TraceProcessorContext context;
  context.storage.reset(new TraceStorage());
  context.global_stack_profile_tracker.reset(new GlobalStackProfileTracker());
  context.heap_profile_tracker.reset(new HeapProfileTracker(&context));

  HeapProfileTracker* hpt = context.heap_profile_tracker.get();
  std::unique_ptr<SequenceStackProfileTracker> spt(
      new SequenceStackProfileTracker(&context));

  constexpr auto kBuildId = 1u;
  constexpr auto kMappingNameId1 = 2u;
  constexpr auto kMappingNameId2 = 3u;

  spt->AddString(kBuildId, "buildid");
  spt->AddString(kMappingNameId1, "foo");
  spt->AddString(kMappingNameId2, "bar");

  SequenceStackProfileTracker::SourceMapping mapping;
  mapping.build_id = kBuildId;
  mapping.exact_offset = 1;
  mapping.start_offset = 1;
  mapping.start = 2;
  mapping.end = 3;
  mapping.load_bias = 0;
  mapping.name_ids = {kMappingNameId1, kMappingNameId2};
  spt->AddMapping(0, mapping);
  hpt->CommitAllocations(kDefaultSequence, spt.get(), nullptr);
  auto foo_bar_id = context.storage->string_pool().GetId("/foo/bar");
  ASSERT_NE(foo_bar_id, std::nullopt);
  EXPECT_THAT(context.storage->stack_profile_mapping_table().name()[0],
              *foo_bar_id);
}

// Insert multiple mappings, frames and callstacks and check result.
TEST(HeapProfileTrackerTest, Functional) {
  TraceProcessorContext context;
  context.storage.reset(new TraceStorage());
  context.global_stack_profile_tracker.reset(new GlobalStackProfileTracker());
  context.heap_profile_tracker.reset(new HeapProfileTracker(&context));

  HeapProfileTracker* hpt = context.heap_profile_tracker.get();
  std::unique_ptr<SequenceStackProfileTracker> spt(
      new SequenceStackProfileTracker(&context));

  uint32_t next_string_intern_id = 1;

  const std::string build_ids[] = {"build1", "build2", "build3"};
  uint32_t build_id_ids[base::ArraySize(build_ids)];
  for (size_t i = 0; i < base::ArraySize(build_ids); ++i)
    build_id_ids[i] = next_string_intern_id++;

  const std::string mapping_names[] = {"map1", "map2", "map3"};
  uint32_t mapping_name_ids[base::ArraySize(mapping_names)];
  for (size_t i = 0; i < base::ArraySize(mapping_names); ++i)
    mapping_name_ids[i] = next_string_intern_id++;

  SequenceStackProfileTracker::SourceMapping
      mappings[base::ArraySize(mapping_names)] = {};
  mappings[0].build_id = build_id_ids[0];
  mappings[0].exact_offset = 1;
  mappings[0].start_offset = 1;
  mappings[0].start = 2;
  mappings[0].end = 3;
  mappings[0].load_bias = 0;
  mappings[0].name_ids = {mapping_name_ids[0], mapping_name_ids[1]};

  mappings[1].build_id = build_id_ids[1];
  mappings[1].exact_offset = 1;
  mappings[1].start_offset = 1;
  mappings[1].start = 2;
  mappings[1].end = 3;
  mappings[1].load_bias = 1;
  mappings[1].name_ids = {mapping_name_ids[1]};

  mappings[2].build_id = build_id_ids[2];
  mappings[2].exact_offset = 1;
  mappings[2].start_offset = 1;
  mappings[2].start = 2;
  mappings[2].end = 3;
  mappings[2].load_bias = 2;
  mappings[2].name_ids = {mapping_name_ids[2]};

  const std::string function_names[] = {"fun1", "fun2", "fun3", "fun4"};
  uint32_t function_name_ids[base::ArraySize(function_names)];
  for (size_t i = 0; i < base::ArraySize(function_names); ++i)
    function_name_ids[i] = next_string_intern_id++;

  SequenceStackProfileTracker::SourceFrame
      frames[base::ArraySize(function_names)];
  frames[0].name_id = function_name_ids[0];
  frames[0].mapping_id = 0;
  frames[0].rel_pc = 123;

  frames[1].name_id = function_name_ids[1];
  frames[1].mapping_id = 0;
  frames[1].rel_pc = 123;

  frames[2].name_id = function_name_ids[2];
  frames[2].mapping_id = 1;
  frames[2].rel_pc = 123;

  frames[3].name_id = function_name_ids[3];
  frames[3].mapping_id = 2;
  frames[3].rel_pc = 123;

  SequenceStackProfileTracker::SourceCallstack callstacks[3];
  callstacks[0] = {2, 1, 0};
  callstacks[1] = {2, 1, 0, 1, 0};
  callstacks[2] = {0, 2, 0, 1, 2};

  for (size_t i = 0; i < base::ArraySize(build_ids); ++i) {
    auto interned = base::StringView(build_ids[i].data(), build_ids[i].size());
    spt->AddString(build_id_ids[i], interned);
  }
  for (size_t i = 0; i < base::ArraySize(mapping_names); ++i) {
    auto interned =
        base::StringView(mapping_names[i].data(), mapping_names[i].size());
    spt->AddString(mapping_name_ids[i], interned);
  }
  for (size_t i = 0; i < base::ArraySize(function_names); ++i) {
    auto interned =
        base::StringView(function_names[i].data(), function_names[i].size());
    spt->AddString(function_name_ids[i], interned);
  }

  for (uint32_t i = 0; i < base::ArraySize(mappings); ++i)
    spt->AddMapping(i, mappings[i]);
  for (uint32_t i = 0; i < base::ArraySize(frames); ++i)
    spt->AddFrame(i, frames[i]);
  for (uint32_t i = 0; i < base::ArraySize(callstacks); ++i)
    spt->AddCallstack(i, callstacks[i]);

  hpt->CommitAllocations(kDefaultSequence, spt.get(), nullptr);

  for (size_t i = 0; i < base::ArraySize(callstacks); ++i) {
    std::optional<CallsiteId> parent;
    const SequenceStackProfileTracker::SourceCallstack& callstack =
        callstacks[i];
    for (size_t depth = 0; depth < callstack.size(); ++depth) {
      auto frame_id = spt->GetDatabaseFrameIdForTesting(callstack[depth]);
      std::optional<CallsiteId> self = FindCallstack(
          *context.storage, static_cast<int64_t>(depth), parent, frame_id);
      ASSERT_TRUE(self.has_value());
      parent = self;
    }
  }

  hpt->FinalizeProfile(kDefaultSequence, spt.get(), nullptr);
}

}  // namespace
}  // namespace trace_processor
}  // namespace perfetto
