// Copyright 2018 The Fuchsia 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 <lib/fpromise/single_threaded_executor.h>
#include <lib/inspect/cpp/hierarchy.h>
#include <lib/inspect/cpp/inspect.h>
#include <lib/inspect/cpp/inspector.h>
#include <lib/inspect/cpp/reader.h>
#include <lib/inspect/cpp/vmo/limits.h>
#include <lib/inspect/cpp/vmo/types.h>

#include <algorithm>
#include <memory>
#include <type_traits>
#include <vector>

#include <zxtest/zxtest.h>

using inspect::Inspector;
using inspect::Node;

namespace {

TEST(Inspect, CreateDeleteActive) {
  Node node;

  {
    auto inspector = std::make_unique<Inspector>();
    EXPECT_TRUE(inspector->DuplicateVmo().get() != ZX_HANDLE_INVALID);
    EXPECT_TRUE(bool(*inspector));
    node = inspector->GetRoot().CreateChild("node");
    Node child = node.CreateChild("child");
    EXPECT_TRUE(bool(child));
  }

  EXPECT_TRUE(bool(node));

  Node child = node.CreateChild("child");
  EXPECT_TRUE(bool(child));
}

TEST(Inspect, VmoName) {
  char name[ZX_MAX_NAME_LEN];
  auto inspector = std::make_unique<Inspector>();
  auto state = inspect::internal::GetState(inspector.get());
  EXPECT_OK(state->GetVmo().get_property(ZX_PROP_NAME, name, sizeof(name)));
  EXPECT_EQ(std::string(name), "InspectHeap");
}

TEST(Inspect, RecordAndDropInspector) {
  Inspector insp;
  insp.GetRoot().CreateChild("name", &insp);

  auto result = inspect::ReadFromVmo(insp.DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();
  ASSERT_EQ(1u, hierarchy.children().size());

  insp.ClearRecorded();

  result = inspect::ReadFromVmo(insp.DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  hierarchy = result.take_value();
  ASSERT_EQ(0u, hierarchy.children().size());
}

TEST(Inspect, CreateNodeWithLongStringReferences) {
  auto inspector = std::make_unique<Inspector>();
  const std::string long_with_extent_data(3000, '.');

  const inspect::StringReference long_with_extent(long_with_extent_data.c_str());

  const auto initial = inspector->GetStats().allocated_blocks;
  constexpr auto number_nodes_created = 1000u;
  std::vector<inspect::Node> nodes(number_nodes_created);
  for (size_t i = 0; i < number_nodes_created; i++) {
    nodes.push_back(inspector->GetRoot().CreateChild(long_with_extent));
  }

  EXPECT_EQ(initial + number_nodes_created + 2, inspector->GetStats().allocated_blocks);

  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();
  ASSERT_EQ(number_nodes_created, hierarchy.children().size());
  std::for_each(std::cbegin(hierarchy.children()), std::cend(hierarchy.children()),
                [&](const auto& child) { EXPECT_EQ(long_with_extent_data, child.name()); });
}

TEST(Inspect, CreateNodeWithLongNames) {
  auto inspector = std::make_unique<Inspector>();
  const std::string long_one_block("This will make an order 1 block");
  const std::string long_with_extent(3000, '.');

  const auto initial = inspector->GetStats().allocated_blocks;

  auto child_one = inspector->GetRoot().CreateChild(long_one_block);
  EXPECT_EQ(initial + 2, inspector->GetStats().allocated_blocks);

  auto child_two = inspector->GetRoot().CreateChild(long_with_extent);
  EXPECT_EQ(initial + 2 + 3, inspector->GetStats().allocated_blocks);

  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();
  ASSERT_EQ(2u, hierarchy.children().size());
  EXPECT_EQ(long_one_block, hierarchy.children()[0].name());
  EXPECT_EQ(long_with_extent, hierarchy.children()[1].name());
}

TEST(Inspect, MixStringReferencesWithRegularStrings) {
  auto inspector = std::make_unique<Inspector>();
  auto regular = inspector->GetRoot().CreateChild("regular");
  auto as_ref = inspector->GetRoot().CreateChild(inspect::StringReference("reference"));
  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  ASSERT_EQ(2u, hierarchy.children().size());
  EXPECT_EQ("regular", hierarchy.children()[0].name());
  EXPECT_EQ("reference", hierarchy.children()[1].name());
}

TEST(Inspect, DeallocateStringReferencesThenAddMore) {
  auto inspector = std::make_unique<Inspector>();
  {
    const inspect::StringReference sr1("first");
    const inspect::StringReference sr2("second");

    auto _ = inspector->GetRoot().CreateChild(sr1);
    auto _i = inspector->GetRoot().CreateChild(sr2);

    auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
    ASSERT_TRUE(result.is_ok());
    auto hierarchy = result.take_value();

    ASSERT_EQ(2u, hierarchy.children().size());
    EXPECT_EQ("first", hierarchy.children()[0].name());
    EXPECT_EQ("second", hierarchy.children()[1].name());
  }

  const inspect::StringReference outer("outer");
  auto _ = inspector->GetRoot().CreateChild(outer);

  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  ASSERT_EQ(1u, hierarchy.children().size());
  EXPECT_EQ("outer", hierarchy.children()[0].name());
}

cpp17::optional<uint64_t> GetGenerationCount(const zx::vmo& vmo) {
  uint8_t bytes[16];
  vmo.read(bytes, 0, sizeof bytes);
  const auto header = reinterpret_cast<inspect::internal::Block*>(bytes);
  return header->payload.u64;
}

cpp17::optional<uint64_t> GetGenerationCount(Inspector* insp) {
  const auto state = inspect::internal::GetState(insp);
  if (state == nullptr) {
    return {};
  }

  return GetGenerationCount(state->GetVmo());
}

TEST(Inspect, DoingFrozenVmoCopy) {
  Inspector inspector;
  inspector.GetRoot().CreateChild("child", &inspector);
  inspector.GetRoot().CreateChild("child2", &inspector);
  const auto result_one = GetGenerationCount(&inspector);
  ASSERT_TRUE(result_one.has_value());
  ASSERT_EQ(4, result_one.value());

  auto frozen_vmo = inspector.FrozenVmoCopy();
  ASSERT_TRUE(frozen_vmo.has_value());

  const auto result = GetGenerationCount(frozen_vmo.value());
  ASSERT_TRUE(result.has_value());
  ASSERT_EQ(inspect::internal::kVmoFrozen, result.value());

  auto original_vmo = inspector.DuplicateVmo();

  for (int i = 0; i < 1000; i++) {
    inspector.GetRoot().CreateInt(std::to_string(i), i, &inspector);
  }

  auto original = inspect::ReadFromVmo(original_vmo);
  ASSERT_TRUE(original.is_ok());
  auto frozen = inspect::ReadFromVmo(frozen_vmo.value());
  ASSERT_TRUE(frozen.is_ok());

  auto original_hierarchy = original.take_value();
  auto frozen_hierarchy = frozen.take_value();

  ASSERT_EQ(1000u, original_hierarchy.node().properties().size());
  ASSERT_EQ(2u, frozen_hierarchy.children().size());
}

TEST(Inspect, TransactionsBlockCopy) {
  Inspector inspector;
  inspector.AtomicUpdate([&](Node& n) { ASSERT_FALSE(inspector.FrozenVmoCopy().has_value()); });
  inspector.AtomicUpdate([&](Node& n) { ASSERT_FALSE(inspector.CopyVmo().has_value()); });
  inspector.AtomicUpdate([&](Node& n) { ASSERT_FALSE(inspector.CopyBytes().has_value()); });
}

TEST(Inspect, UsingStringReferencesAsNames) {
  auto inspector = std::make_unique<Inspector>();
  const inspect::StringReference one("one");
  const inspect::StringReference two("two");

  auto child_one = inspector->GetRoot().CreateChild(one);
  auto child_two = inspector->GetRoot().CreateChild(two);

  const auto after_children = inspector->GetStats().allocated_blocks;

  auto child_one_child_two = child_one.CreateChild(two);
  auto child_two_child_one = child_two.CreateChild(one);

  const auto after_more_children = inspector->GetStats().allocated_blocks;
  // the +2 are the child blocks, note that no name/string_reference is allocated
  EXPECT_EQ(after_children + 2, after_more_children);

  { auto c = child_one.CreateChild(one); }
  // The 1 is the child created in the above block. Note that
  // a new NAME or STRING_REFERENCE is *not* allocated and therefore
  // not deallocated.
  EXPECT_EQ(inspector->GetStats().deallocated_blocks, 1);

  auto c = child_one.CreateChild(inspect::StringReference("a new string reference"));

  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  // children of root
  ASSERT_EQ(2u, hierarchy.children().size());
  EXPECT_EQ("one", hierarchy.children()[1].name());
  EXPECT_EQ("two", hierarchy.children()[0].name());

  // children of child_one
  ASSERT_EQ(2u, hierarchy.children()[1].children().size());
  EXPECT_EQ("two", hierarchy.children()[1].children()[0].name());
  EXPECT_EQ("a new string reference", hierarchy.children()[1].children()[1].name());

  // children of child_two
  ASSERT_EQ(1u, hierarchy.children()[0].children().size());
  EXPECT_EQ("one", hierarchy.children()[0].children()[0].name());

  // Inspector::State::~Heap will ensure that release is done properly,
  // so this unit test ensures that StringReferences are correctly refcounted
  // and released/destroyed/deallocated.
}

TEST(Inspect, CreateLazyNodeWithStringReferences) {
  const inspect::StringReference lazy("lazy");
  Inspector inspector;
  inspector.GetRoot().CreateLazyNode(
      lazy,
      [] {
        Inspector insp;
        insp.GetRoot().CreateInt("val", 10, &insp);
        return fpromise::make_ok_promise(insp);
      },
      &inspector);

  auto children = inspector.GetChildNames();
  ASSERT_EQ(1u, children.size());
  EXPECT_EQ("lazy-0", children[0]);

  auto stats = inspector.GetStats();
  EXPECT_EQ(1u, stats.dynamic_child_count);

  fpromise::result<Inspector> result;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspector.OpenChild("lazy-0").then(
      [&](fpromise::result<Inspector>& res) { result = std::move(res); }));
  exec.run();
  EXPECT_TRUE(result.is_ok());
}

TEST(Inspect, CreateChildren) {
  auto inspector = std::make_unique<Inspector>();
  Node child = inspector->GetRoot().CreateChild("child");
  EXPECT_TRUE(bool(child));

  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  ASSERT_EQ(1u, hierarchy.children().size());
  EXPECT_EQ("child", hierarchy.children()[0].name());
}

TEST(Inspect, CreateCopyVmo) {
  auto inspector = std::make_unique<Inspector>();

  // Store a string.
  std::string s = "abcd";
  auto property = inspector->GetRoot().CreateString("string", s);
  auto result = inspect::ReadFromVmo(inspector->CopyVmo().value());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  auto* string_value = hierarchy.node().get_property<inspect::StringPropertyValue>("string");
  ASSERT_TRUE(string_value != nullptr);
  EXPECT_EQ(s, string_value->value());
}

constexpr size_t kPageSize = 4096;

TEST(Inspect, CreateGetStats) {
  // Limit to 2 pages.
  Inspector inspector(inspect::InspectSettings{.maximum_size = 2 * kPageSize});

  auto stats = inspector.GetStats();
  EXPECT_EQ(1 * kPageSize, stats.size);
  EXPECT_EQ(2 * kPageSize, stats.maximum_size);
  EXPECT_EQ(0, stats.dynamic_child_count);

  // Fill up the buffer
  for (int i = 0; i < 1000; i++) {
    inspector.GetRoot().CreateString(std::to_string(i), "This is a test", &inspector);
  }

  stats = inspector.GetStats();
  EXPECT_EQ(2 * kPageSize, stats.size);
  EXPECT_EQ(2 * kPageSize, stats.maximum_size);
  EXPECT_EQ(0, stats.dynamic_child_count);
}

TEST(Inspect, StringArrays) {
  Inspector inspector;

  const inspect::StringReference array_name("array_name");
  const inspect::StringReference shared_ref("shared_ref");
  const std::string big(inspect::internal::kMaxOrderSize + 1, '.');

  auto property = inspector.GetRoot().CreateInt(shared_ref, 5);

  {
    auto array = inspector.GetRoot().CreateStringArray(array_name, 5);
    array.Set(0, "zero");
    array.Set(1, shared_ref);
    array.Set(3, big);

    auto bytes = inspector.CopyBytes().value();
    auto result = inspect::ReadFromBuffer(std::move(bytes));
    ASSERT_TRUE(result.is_ok());
    auto hierarchy = result.take_value();
    hierarchy.Sort();

    EXPECT_EQ(0u, hierarchy.children().size());
    EXPECT_EQ(2u, hierarchy.node().properties().size());

    const auto& int_prop = hierarchy.node().properties().at(1);
    const auto& array_prop = hierarchy.node().properties().at(0);

    EXPECT_EQ(shared_ref.Data(), int_prop.name());
    EXPECT_EQ(array_name.Data(), array_prop.name());

    const auto& array_data = array_prop.Get<inspect::StringArrayValue>().value();

    EXPECT_EQ("zero", array_data.at(0));
    EXPECT_EQ(shared_ref.Data(), array_data.at(1));
    EXPECT_TRUE(array_data.at(2).empty());
    EXPECT_EQ(big, array_data.at(3));
    EXPECT_TRUE(array_data.at(4).empty());
  }

  auto bytes = inspector.CopyBytes().value();
  auto result = inspect::ReadFromBuffer(std::move(bytes));
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();
  hierarchy.Sort();

  EXPECT_EQ(0u, hierarchy.children().size());
  EXPECT_EQ(1u, hierarchy.node().properties().size());

  const auto& int_prop = hierarchy.node().properties().at(0);

  EXPECT_EQ(shared_ref.Data(), int_prop.name());
}

namespace {
const char* FUCHSIA_INSPECT_STATS = "fuchsia.inspect.Stats-0";
}

void ReadChildHierarchy(Inspector* inspector, inspect::Hierarchy* hierarchy, std::string name) {
  fpromise::result<Inspector> res1;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspector->OpenChild(name).then(
      [&](fpromise::result<Inspector>& res) { res1 = std::move(res); }));
  exec.run();
  ASSERT_TRUE(res1.is_ok());

  auto res2 = inspect::ReadFromVmo(res1.value().DuplicateVmo());
  ASSERT_TRUE(res2.is_ok());
  *hierarchy = res2.take_value();
}

void CheckStats(const inspect::Hierarchy* hierarchy, const inspect::InspectStats* expected) {
  auto current_size_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("current_size");
  ASSERT_TRUE(current_size_value != nullptr);
  ASSERT_EQ(expected->size, current_size_value->value());
  auto maximum_size_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("maximum_size");
  ASSERT_TRUE(maximum_size_value != nullptr);
  ASSERT_EQ(expected->maximum_size, maximum_size_value->value());
  auto total_dynamic_children_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("total_dynamic_children");
  ASSERT_TRUE(total_dynamic_children_value != nullptr);
  ASSERT_EQ(expected->dynamic_child_count, total_dynamic_children_value->value());
  auto allocated_blocks_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("allocated_blocks");
  ASSERT_TRUE(allocated_blocks_value != nullptr);
  ASSERT_EQ(expected->allocated_blocks, allocated_blocks_value->value());
  auto deallocated_blocks_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("deallocated_blocks");
  ASSERT_TRUE(deallocated_blocks_value != nullptr);
  ASSERT_EQ(expected->deallocated_blocks, deallocated_blocks_value->value());
  auto failed_allocations_value =
      hierarchy->node().get_property<inspect::UintPropertyValue>("failed_allocations");
  ASSERT_TRUE(failed_allocations_value != nullptr);
  ASSERT_EQ(expected->failed_allocations, failed_allocations_value->value());
}

TEST(Inspect, CreateStatsNode) {
  // Limit to 2 pages.
  Inspector inspector(inspect::InspectSettings{.maximum_size = 2 * kPageSize});
  inspector.CreateStatsNode();

  auto children = inspector.GetChildNames();
  ASSERT_EQ(1u, children.size());
  EXPECT_EQ(FUCHSIA_INSPECT_STATS, children[0]);

  inspect::Hierarchy hierarchy;
  ReadChildHierarchy(&inspector, &hierarchy, FUCHSIA_INSPECT_STATS);

  inspect::InspectStats expected = {};
  expected.size = 1 * kPageSize;
  expected.maximum_size = 2 * kPageSize;
  expected.dynamic_child_count = 1u;
  expected.allocated_blocks = 4u;
  expected.deallocated_blocks = 0u;
  expected.failed_allocations = 0u;
  CheckStats(&hierarchy, &expected);

  for (int i = 0; i < 100; i++) {
    inspector.GetRoot().CreateString(std::to_string(i), "This is a test", &inspector);
  }

  ReadChildHierarchy(&inspector, &hierarchy, FUCHSIA_INSPECT_STATS);

  expected.size = 2 * kPageSize;
  expected.maximum_size = 2 * kPageSize;
  expected.dynamic_child_count = 1u;
  expected.allocated_blocks = 304u;
  expected.deallocated_blocks = 0u;
  expected.failed_allocations = 0u;
  CheckStats(&hierarchy, &expected);

  for (int i = 101; i < 128; i++) {
    inspector.GetRoot().CreateString(std::to_string(i), "This is a test", &inspector);
  }

  ReadChildHierarchy(&inspector, &hierarchy, FUCHSIA_INSPECT_STATS);

  expected.size = 2 * kPageSize;
  expected.maximum_size = 2 * kPageSize;
  expected.dynamic_child_count = 1u;
  expected.allocated_blocks = 381u;
  expected.deallocated_blocks = 2u;
  expected.failed_allocations = 2u;
  CheckStats(&hierarchy, &expected);
}

TEST(Inspect, GetLinks) {
  Inspector inspector;

  inspector.GetRoot().CreateLazyNode(
      "lazy",
      [] {
        Inspector insp;
        insp.GetRoot().CreateInt("val", 10, &insp);
        return fpromise::make_ok_promise(insp);
      },
      &inspector);

  auto children = inspector.GetChildNames();
  ASSERT_EQ(1u, children.size());
  EXPECT_EQ("lazy-0", children[0]);

  auto stats = inspector.GetStats();
  EXPECT_EQ(1u, stats.dynamic_child_count);

  fpromise::result<Inspector> result;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspector.OpenChild("lazy-0").then(
      [&](fpromise::result<Inspector>& res) { result = std::move(res); }));
  exec.run();
  EXPECT_TRUE(result.is_ok());
}

TEST(Inspect, LinksAreDestructed) {
  Inspector inspector;

  auto ln = inspector.GetRoot().CreateLazyNode("lazy", [] {
    Inspector insp;
    insp.GetRoot().CreateInt("val", 10, &insp);
    return fpromise::make_ok_promise(insp);
  });

  auto children = inspector.GetChildNames();
  ASSERT_EQ(1u, children.size());
  EXPECT_EQ("lazy-0", children[0]);

  auto stats = inspector.GetStats();
  EXPECT_EQ(1u, stats.dynamic_child_count);

  fpromise::result<Inspector> result;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspector.OpenChild("lazy-0").then(
      [&](fpromise::result<Inspector>& res) { result = std::move(res); }));
  exec.run();
  EXPECT_TRUE(result.is_ok());

  // clear node, shouldn't be in Inspector
  ln = inspect::LazyNode();

  children = inspector.GetChildNames();
  EXPECT_EQ(0u, children.size());

  stats = inspector.GetStats();
  EXPECT_EQ(0u, stats.dynamic_child_count);
}

TEST(Inspect, LazyNodesAreDestructed) {
  Inspector inspector;

  auto ln = inspector.GetRoot().CreateLazyNode("lazy", [] {
    Inspector insp;
    insp.GetRoot().CreateInt("val", 10, &insp);
    return fpromise::make_ok_promise(std::move(insp));
  });

  fpromise::result<inspect::Hierarchy> result;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspect::ReadFromInspector(inspector).then(
      [&](fpromise::result<inspect::Hierarchy>& res) { result = std::move(res); }));
  exec.run();

  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  EXPECT_EQ(1, hierarchy.children().size());
  EXPECT_EQ("lazy", hierarchy.children()[0].name());
  EXPECT_EQ(
      10, hierarchy.children()[0].node().properties()[0].Get<inspect::IntPropertyValue>().value());

  // this should clear the node
  ln = inspect::LazyNode();

  // inspector is empty
  exec.schedule_task(inspect::ReadFromInspector(inspector).then(
      [&](fpromise::result<inspect::Hierarchy>& res) { result = std::move(res); }));
  exec.run();

  ASSERT_TRUE(result.is_ok());
  hierarchy = result.take_value();

  EXPECT_EQ(0, hierarchy.children().size());
}

TEST(Inspect, NamedLazyNodesAreDestructed) {
  Inspector inspector;

  auto ln = inspector.GetRoot().CreateLazyNode("lazy", [] {
    Inspector insp;
    insp.GetRoot().CreateInt("val", 10, &insp);
    return fpromise::make_ok_promise(std::move(insp));
  });

  auto second = inspector.GetRoot().CreateLazyNode("lazy-2", [] {
    Inspector insp;
    insp.GetRoot().CreateInt("val-2", 10, &insp);
    return fpromise::make_ok_promise(std::move(insp));
  });

  fpromise::result<inspect::Hierarchy> result;
  fpromise::single_threaded_executor exec;
  exec.schedule_task(inspect::ReadFromInspector(inspector).then(
      [&](fpromise::result<inspect::Hierarchy>& res) { result = std::move(res); }));
  exec.run();

  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  EXPECT_EQ(2, hierarchy.children().size());
  EXPECT_EQ("lazy", hierarchy.children()[0].name());
  EXPECT_EQ("lazy-2", hierarchy.children()[1].name());
  EXPECT_EQ(
      10, hierarchy.children()[0].node().properties()[0].Get<inspect::IntPropertyValue>().value());
  EXPECT_EQ(
      10, hierarchy.children()[1].node().properties()[0].Get<inspect::IntPropertyValue>().value());

  // remove second from VMO, replacing it with contents of ln
  // result is as if we had removed second
  second = std::move(ln);

  exec.schedule_task(inspect::ReadFromInspector(inspector).then(
      [&](fpromise::result<inspect::Hierarchy>& res) { result = std::move(res); }));
  exec.run();

  ASSERT_TRUE(result.is_ok());
  hierarchy = result.take_value();

  EXPECT_EQ(1, hierarchy.children().size());
  EXPECT_EQ("lazy", hierarchy.children()[0].name());
  EXPECT_EQ(
      10, hierarchy.children()[0].node().properties()[0].Get<inspect::IntPropertyValue>().value());
}

TEST(Inspect, CreateCopyBytes) {
  // Make a 16MB heap.
  auto inspector = std::make_unique<Inspector>();

  // Store a string.
  std::string s = "abcd";
  auto property = inspector->GetRoot().CreateString("string", s);

  auto bytes = inspector->CopyBytes().value();
  auto result = inspect::ReadFromBuffer(std::move(bytes));
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  EXPECT_EQ(s, hierarchy.node().properties()[0].Get<inspect::StringPropertyValue>().value());
}

TEST(Inspect, CreateLargeHeap) {
  // Make a 16MB heap.
  auto inspector =
      std::make_unique<Inspector>(inspect::InspectSettings{.maximum_size = 16 * 1024 * 1024});

  // Store a 4MB string.
  std::string s(4 * 1024 * 1024, 'a');
  auto property = inspector->GetRoot().CreateString("big_string", s);
  auto result = inspect::ReadFromVmo(inspector->DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  EXPECT_EQ(s, hierarchy.node().properties()[0].Get<inspect::StringPropertyValue>().value());
}

TEST(Inspect, CreateInvalidSize) {
  auto inspector = std::make_unique<Inspector>(inspect::InspectSettings{.maximum_size = 0});
  EXPECT_TRUE(inspector->DuplicateVmo().get() == ZX_HANDLE_INVALID);
  EXPECT_FALSE(bool(inspector->GetRoot()));
  EXPECT_FALSE(bool(*inspector));
}

TEST(Inspect, CreateWithVmoInvalidSize) {
  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(0 /* size */, 0, &vmo));
  Inspector inspector(std::move(vmo));
  auto stats = inspector.GetStats();
  EXPECT_EQ(0, stats.size);
  EXPECT_EQ(0, stats.maximum_size);
  EXPECT_EQ(0, stats.dynamic_child_count);
  EXPECT_FALSE(bool(inspector));
}

TEST(Inspect, CreateWithVmoReadOnly) {
  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(4096 /* size */, 0, &vmo));

  zx::vmo duplicate;
  ASSERT_OK(vmo.duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ, &duplicate));
  Inspector inspector(std::move(duplicate));
  auto stats = inspector.GetStats();
  EXPECT_EQ(0, stats.size);
  EXPECT_EQ(0, stats.maximum_size);
  EXPECT_EQ(0, stats.dynamic_child_count);
  EXPECT_FALSE(bool(inspector));
}

TEST(Inspect, CreateWithVmoDuplicateVmo) {
  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(4096 /* size */, 0, &vmo));

  zx::vmo duplicate;
  ASSERT_OK(
      vmo.duplicate(ZX_RIGHTS_BASIC | ZX_RIGHT_READ | ZX_RIGHT_WRITE | ZX_RIGHT_MAP, &duplicate));
  Inspector inspector(std::move(duplicate));
  auto stats = inspector.GetStats();
  EXPECT_EQ(4096, stats.size);
  EXPECT_EQ(4096, stats.maximum_size);
  EXPECT_TRUE(bool(inspector));
}

TEST(Inspect, CreateWithDirtyVmo) {
  zx::vmo vmo;
  ASSERT_OK(zx::vmo::create(4096 /* size */, 0, &vmo));

  // Write data into the VMO before using it, internally we will decommit
  // the pages to zero them.
  std::vector<uint8_t> bytes(4096, 'a');
  ASSERT_OK(vmo.write(bytes.data(), 0, bytes.size()));

  Inspector inspector(std::move(vmo));
  ASSERT_TRUE(bool(inspector));
  auto val = inspector.GetRoot().CreateUint("test", 100);

  auto result = inspect::ReadFromVmo(inspector.DuplicateVmo());
  ASSERT_TRUE(result.is_ok());
  auto hierarchy = result.take_value();

  EXPECT_EQ(1, hierarchy.node().properties().size());
  EXPECT_EQ("test", hierarchy.node().properties()[0].name());
  EXPECT_EQ(100, hierarchy.node().properties()[0].Get<inspect::UintPropertyValue>().value());

  auto stats = inspector.GetStats();
  EXPECT_EQ(4096, stats.size);
  EXPECT_EQ(4096, stats.maximum_size);
}

TEST(Inspect, UniqueName) {
  inspect::Inspector inspector1, inspector2;
  EXPECT_EQ("root0x0", inspector1.GetRoot().UniqueName("root"));
  EXPECT_EQ("root0x1", inspector1.GetRoot().UniqueName("root"));
  EXPECT_EQ("root0x2", inspector1.GetRoot().UniqueName("root"));
  EXPECT_EQ("test0x3", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x4", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x5", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x6", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x7", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x8", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x9", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xa", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xb", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xc", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xd", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xe", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0xf", inspector1.GetRoot().UniqueName("test"));
  EXPECT_EQ("test0x10", inspector1.GetRoot().UniqueName("test"));

  EXPECT_EQ("root0x0", inspector2.GetRoot().UniqueName("root"));
}

TEST(Inspect, UniqueNameNoop) {
  inspect::Node noop;
  EXPECT_EQ("", noop.UniqueName("root"));
  EXPECT_EQ("", noop.UniqueName("test"));
}

}  // namespace
