// Copyright 2019 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/expr/resolve_base.h"

#include <gtest/gtest.h>

#include "llvm/BinaryFormat/Dwarf.h"
#include "src/developer/debug/zxdb/common/test_with_loop.h"
#include "src/developer/debug/zxdb/expr/abi_null.h"
#include "src/developer/debug/zxdb/expr/mock_eval_context.h"
#include "src/developer/debug/zxdb/expr/test_eval_context_impl.h"
#include "src/developer/debug/zxdb/expr/virtual_base_test_setup.h"
#include "src/developer/debug/zxdb/symbols/collection.h"
#include "src/developer/debug/zxdb/symbols/elf_symbol.h"
#include "src/developer/debug/zxdb/symbols/inherited_from.h"
#include "src/developer/debug/zxdb/symbols/location.h"
#include "src/developer/debug/zxdb/symbols/mock_module_symbols.h"
#include "src/developer/debug/zxdb/symbols/mock_symbol_data_provider.h"
#include "src/developer/debug/zxdb/symbols/modified_type.h"
#include "src/developer/debug/zxdb/symbols/process_symbols_test_setup.h"
#include "src/developer/debug/zxdb/symbols/type_test_support.h"

namespace zxdb {

namespace {

class ResolveBase : public TestWithLoop {};

}  // namespace

// Given a class without a vtable, verifies that the DerivedTypeForVtable does a synchronous no-op.
TEST_F(ResolveBase, PromotePtrRefToDerived_NoVtable) {
  auto eval_context = fxl::MakeRefCounted<MockEvalContext>();

  auto not_virtual =
      MakeCollectionType(DwarfTag::kStructureType, "MyStruct", {{"a", MakeInt32Type()}});
  std::vector<uint8_t> data{42, 0, 0, 0};  // int32_t = 42.

  ExprValue value(not_virtual, data);

  bool called = false;
  PromotePtrRefToDerived(eval_context, PromoteToDerived::kPtrOrRef, value,
                         [&called, original_value = value](ErrOrValue result) {
                           called = true;
                           EXPECT_TRUE(result.ok());
                           EXPECT_EQ(original_value, result.value());

                           // In this test the type object pointers should be the same (not normally
                           // tested in value equality) since the value should be the same one just
                           // forwarded.
                           EXPECT_EQ(original_value.type(), result.value().type());
                         });
  EXPECT_TRUE(called);
}

TEST_F(ResolveBase, PromotePtrRefToDerived) {
  ProcessSymbolsTestSetup symbol_setup;
  MockModuleSymbols* mock_module_symbols = symbol_setup.InjectMockModule();
  SymbolContext symbol_context(ProcessSymbolsTestSetup::kDefaultLoadAddress);

  auto symbol_data_provider = fxl::MakeRefCounted<MockSymbolDataProvider>();
  auto eval_context = fxl::MakeRefCounted<TestEvalContextImpl>(
      std::make_shared<AbiNull>(), symbol_setup.process().GetWeakPtr(), symbol_data_provider,
      ExprLanguage::kC);

  VirtualBaseTestSetup setup(symbol_data_provider.get(), mock_module_symbols);

  // Add a bunch of qualifiers to make sure they come out the other end.
  auto const_base_class = fxl::MakeRefCounted<ModifiedType>(DwarfTag::kConstType, setup.base_class);
  auto ptr_const_base_class =
      fxl::MakeRefCounted<ModifiedType>(DwarfTag::kPointerType, const_base_class);
  auto const_ptr_const_base_class =
      fxl::MakeRefCounted<ModifiedType>(DwarfTag::kConstType, ptr_const_base_class);

  // Input Base*.
  ExprValue base_ptr(setup.kBaseAddress, const_ptr_const_base_class);

  // -----------------------------------------------------------------------------------------------
  // Part 1: vtable pointer points to "Derived".

  // The default setup will have the vtable point to the derived class.
  ErrOrValue result(Err("Not called"));
  PromotePtrRefToDerived(eval_context, PromoteToDerived::kPtrOrRef, base_ptr,
                         [&result](ErrOrValue r) { result = r; });
  loop().RunUntilNoTasks();
  ASSERT_TRUE(result.ok());

  // Now that the memory has been hooked up, the result should be a const*const (consts copied from
  // the original base type) with the derived address.
  uint64_t result64 = 0;
  ASSERT_TRUE(result.value().PromoteTo64(&result64).ok());
  EXPECT_EQ(setup.kDerivedAddress, result64);
  EXPECT_EQ("const DerivedClass* const", result.value().type()->GetFullName());

  // -----------------------------------------------------------------------------------------------
  // Part 2: vtable pointer points to "Base".

  // Fix up the vtable pointer to the base class.
  Location vtable_location(setup.kVtableAbsoluteAddress, FileLine(), 0, symbol_context,
                           setup.base_vtable);
  mock_module_symbols->AddSymbolLocations(setup.kVtableAbsoluteAddress, {vtable_location});

  result = Err("Not called");
  PromotePtrRefToDerived(eval_context, PromoteToDerived::kPtrOrRef, base_ptr,
                         [&result](ErrOrValue r) { result = r; });
  loop().RunUntilNoTasks();
  ASSERT_TRUE(result.ok()) << result.err().msg();
  EXPECT_EQ(base_ptr, result.value());  // Should give same input as output.

  // -----------------------------------------------------------------------------------------------
  // Part 3: vtable pointer is invalid.

  // Declare no symbol at this address.
  mock_module_symbols->AddSymbolLocations(
      setup.kVtableAbsoluteAddress,
      {Location(Location::State::kSymbolized, setup.kVtableAbsoluteAddress)});

  // Should run asynchronously and produce success.
  result = Err("Not called");
  PromotePtrRefToDerived(eval_context, PromoteToDerived::kPtrOrRef, base_ptr,
                         [&result](ErrOrValue r) { result = r; });
  loop().RunUntilNoTasks();
  ASSERT_TRUE(result.ok());

  // We did not hook up the vtable memory above so the resolution will fail. It should fall back on
  // returning the input rather than forwarding an error.
  EXPECT_EQ(base_ptr, result.value());
  EXPECT_EQ("const BaseClass* const", result.value().type()->GetFullName());

  // -----------------------------------------------------------------------------------------------
  // Part 4: virtual inheritance means we can't promote to derived.

  // Put back the good derived vtable location cleared in the previous step so it will succeed.
  mock_module_symbols->AddSymbolLocations(setup.kVtableAbsoluteAddress,
                                          {Location(setup.kVtableAbsoluteAddress, FileLine(), 0,
                                                    symbol_context, setup.derived_vtable)});

  // Replace the inheritance record with one indicating virtual inheritance. This placeholder
  // expression won't work in practice (see VirtualInheritanceTestSetup for a real one) but the
  // presence of some expression will trigger a casting failure.
  auto virtual_inheritance =
      fxl::MakeRefCounted<InheritedFrom>(setup.base_class, DwarfExpr({llvm::dwarf::DW_OP_dup}));
  setup.derived_class->set_inherited_from({LazySymbol(virtual_inheritance)});

  result = Err("Not called");
  PromotePtrRefToDerived(eval_context, PromoteToDerived::kPtrOrRef, base_ptr,
                         [&result](ErrOrValue r) { result = r; });
  loop().RunUntilNoTasks();
  ASSERT_TRUE(result.ok()) << result.err().msg();
  EXPECT_EQ(base_ptr, result.value());  // Should give same input as output.
}

}  // namespace zxdb
