// 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/call_site.h"
#include "src/developer/debug/zxdb/symbols/call_site_parameter.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].range = AddressRange(0x1000, 0x2000);
  loc_entries[0].expression = DwarfExpr({0x30,  // DW_OP_lit0
                                         0x71,  // DW_OP_breg1
                                         1});   // 1 (param for breg).

  loc_entries[1].range = AddressRange(0x3000, 0x4000);
  loc_entries[1].expression = DwarfExpr({0x31});  // DW_OP_lit1

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

  FormatSymbolOptions opts;
  opts.arch = debug::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()->As<DataMember>())->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, DwarfExpr({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"
      "  Calling convention: DW_CC_normal\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());
}

TEST(FormatSymbol, CallSite) {
  DwarfExpr value_expr({0x30,  // DW_OP_lit0
                        0x71,  // DW_OP_breg1
                        1});   // 1 (param for breg).
  auto param1 = fxl::MakeRefCounted<CallSiteParameter>(5, value_expr);
  auto param2 = fxl::MakeRefCounted<CallSiteParameter>(6, value_expr);

  auto call = fxl::MakeRefCounted<CallSite>(0x1000, std::vector<LazySymbol>{param1, param2});

  OutputBuffer out = FormatSymbol(nullptr, call.get(), FormatSymbolOptions());
  EXPECT_EQ(
      "Call Site\n"
      "  Return to: 0x1000\n"
      "  Parameters:\n"
      "    Call site parameter:\n"
      "      DWARF register #: 5\n"
      "      Value expression: push(0), dwarf_register(1) + 1\n"
      "    Call site parameter:\n"
      "      DWARF register #: 6\n"
      "      Value expression: push(0), dwarf_register(1) + 1\n",
      out.AsString());
}

}  // namespace zxdb
