// Copyright 2020 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 "src/developer/debug/zxdb/console/format_symbol.h"

#include <gtest/gtest.h>

#include "src/developer/debug/zxdb/symbols/data_member.h"
#include "src/developer/debug/zxdb/symbols/inherited_from.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"
#include "src/developer/debug/zxdb/symbols/variable.h"

namespace zxdb {

TEST(FormatSymbol, Variable) {
  auto int32_type = MakeInt32Type();

  std::vector<VariableLocation::Entry> loc_entries;
  loc_entries.resize(2);
  loc_entries[0].begin = 0x1000;
  loc_entries[0].end = 0x2000;
  loc_entries[0].expression.push_back(0x30);  // DW_OP_lit0
  loc_entries[0].expression.push_back(0x71);  // DW_OP_breg1
  loc_entries[0].expression.push_back(1);     // 1 (param for breg).

  loc_entries[1].begin = 0x3000;
  loc_entries[1].end = 0x4000;
  loc_entries[1].expression.push_back(0x31);  // DW_OP_lit1

  auto var = fxl::MakeRefCounted<Variable>(DwarfTag::kVariable, "my_var", int32_type,
                                           VariableLocation(loc_entries));

  FormatSymbolOptions opts;
  opts.arch = debug_ipc::Arch::kX64;

  // Format expressions as bytes.
  opts.dwarf_expr = FormatSymbolOptions::DwarfExpr::kBytes;
  OutputBuffer out = FormatSymbol(nullptr, var.get(), opts);
  const char kExpectedBytes[] =
      "Variable: my_var\n"
      "  Type: int32_t\n"
      "  DWARF tag: DW_TAG_variable (0x34)\n"
      "  DWARF location (address range + DWARF expression):\n"
      "    [0x1000, 0x2000): 0x30 0x71 0x01\n"
      "    [0x3000, 0x4000): 0x31\n";
  EXPECT_EQ(kExpectedBytes, out.AsString());

  // Format expressions as DWARF operations.
  opts.dwarf_expr = FormatSymbolOptions::DwarfExpr::kOps;
  out = FormatSymbol(nullptr, var.get(), opts);
  const char kExpectedOps[] =
      "Variable: my_var\n"
      "  Type: int32_t\n"
      "  DWARF tag: DW_TAG_variable (0x34)\n"
      "  DWARF location (address range + DWARF expression):\n"
      "    [0x1000, 0x2000): DW_OP_lit0, DW_OP_breg1(1)\n"
      "    [0x3000, 0x4000): DW_OP_lit1\n";
  EXPECT_EQ(kExpectedOps, out.AsString());

  // Pretty formatting of expressions.
  opts.dwarf_expr = FormatSymbolOptions::DwarfExpr::kPretty;
  out = FormatSymbol(nullptr, var.get(), opts);
  const char kExpectedPretty[] =
      "Variable: my_var\n"
      "  Type: int32_t\n"
      "  DWARF tag: DW_TAG_variable (0x34)\n"
      "  DWARF location (address range + DWARF expression):\n"
      "    [0x1000, 0x2000): push(0), register(rdx) + 1\n"
      "    [0x3000, 0x4000): push(1)\n";
  EXPECT_EQ(kExpectedPretty, out.AsString());
}

TEST(FormatSymbol, BaseType) {
  auto int32_type = MakeInt32Type();
  OutputBuffer out = FormatSymbol(nullptr, int32_type.get(), FormatSymbolOptions());
  const char kExpected[] =
      "Type: int32_t\n"
      "  DWARF tag: DW_TAG_base_type (0x24)\n"
      "  Byte size: 4\n"
      "  DWARF base type: DW_ATE_signed (0x05)\n";
  EXPECT_EQ(kExpected, out.AsString());
}

TEST(FormatSymbol, Collection) {
  auto int32_type = MakeInt32Type();

  // Create a collection. The second member leaves a gap so we can test padding.
  auto coll = MakeCollectionType(DwarfTag::kStructureType, "MyStruct",
                                 {{"a", int32_type}, {"b", int32_type}});
  // This const cast is evil but it's cleaner to use the test utilities to create all the data
  // members and then reach in and make them the way we want (with extra padding) than duplicate all
  // of that logic.
  const_cast<DataMember*>(coll->data_members()[1].Get()->AsDataMember())->set_member_location(8);
  coll->set_byte_size(12);

  // Say it inherits from this empty base class. Since it's empty, it will start at the same offset
  // as the first member.
  auto base_type = MakeCollectionType(DwarfTag::kStructureType, "BaseStruct", {});
  auto base_from = fxl::MakeRefCounted<InheritedFrom>(base_type, 0);

  // Virtual inheritance has no location but an expression to compute it. We use a dummy expression.
  auto virtual_base_type = MakeCollectionType(DwarfTag::kStructureType, "VirtualBase", {});
  auto virtual_base_from =
      fxl::MakeRefCounted<InheritedFrom>(virtual_base_type, std::vector<uint8_t>{0x01});

  coll->set_inherited_from({LazySymbol(base_from), LazySymbol(virtual_base_from)});

  OutputBuffer out = FormatSymbol(nullptr, coll.get(), FormatSymbolOptions());
  const char kExpectedHeader[] =
      "Type: MyStruct\n"
      "  DWARF tag: DW_TAG_structure_type (0x13)\n"
      "  Byte size: 12\n";
  const char kMembers[] =  // Split off to allow re-use below.
      "  Members:\n"
      "       Offset Size Name         Type\n"
      "    <virtual>    0 <base class> VirtualBase\n"
      "            0    0 <base class> BaseStruct\n"
      "            0    4 a            int32_t\n"
      "            4    4              <padding>\n"
      "            8    4 b            int32_t\n";
  EXPECT_EQ(std::string(kExpectedHeader) + std::string(kMembers), out.AsString());

  // Re-test with a typedef. Typedefs of structures should show the members.
  auto coll_typedef = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kTypedef, coll);
  coll_typedef->set_assigned_name("MyTypedef");
  const char kTypedefHeader[] =
      "Type: MyTypedef\n"
      "  DWARF tag: DW_TAG_typedef (0x16)\n"
      "  Byte size: 12\n"
      "  Underlying type: MyStruct\n";
  out = FormatSymbol(nullptr, coll_typedef.get(), FormatSymbolOptions());
  EXPECT_EQ(std::string(kTypedefHeader) + std::string(kMembers), out.AsString());
}

}  // namespace zxdb
