// 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/console/format_location.h"

#include <gtest/gtest.h>

#include "src/developer/debug/zxdb/client/session.h"
#include "src/developer/debug/zxdb/console/console_context.h"
#include "src/developer/debug/zxdb/symbols/elf_symbol.h"
#include "src/developer/debug/zxdb/symbols/function.h"
#include "src/developer/debug/zxdb/symbols/location.h"
#include "src/developer/debug/zxdb/symbols/process_symbols_test_setup.h"
#include "src/developer/debug/zxdb/symbols/symbol_context.h"

namespace zxdb {

TEST(FormatLocation, FormatLocation_Function) {
  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  FormatLocationOptions no_addrs_no_params;
  no_addrs_no_params.always_show_addresses = false;
  no_addrs_no_params.show_file_line = true;
  EXPECT_EQ("<invalid address>", FormatLocation(Location(), no_addrs_no_params).AsString());

  // Address-only location.
  EXPECT_EQ(
      "0x12345",
      FormatLocation(Location(Location::State::kAddress, 0x12345), no_addrs_no_params).AsString());

  // Function-only location.
  fxl::RefPtr<Function> function(fxl::MakeRefCounted<Function>(DwarfTag::kSubprogram));
  function->set_assigned_name("Func");
  function->set_code_ranges(AddressRanges(AddressRange(0x1200, 0x1300)));
  EXPECT_EQ(
      "Func() + 0x34 (no line info)",
      FormatLocation(Location(0x1234, FileLine(), 0, symbol_context, function), no_addrs_no_params)
          .AsString());

  // Same as above but location is before the function address (probably something is corrupt). It
  // should omit the offset.
  EXPECT_EQ("Func()", FormatLocation(Location(0x1100, FileLine(), 0, symbol_context, function),
                                     no_addrs_no_params)
                          .AsString());

  // File/line present but not shown.
  FormatLocationOptions no_file_line;
  no_file_line.always_show_addresses = false;
  no_file_line.show_file_line = false;
  Location loc(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context, function);
  EXPECT_EQ("Func() + 0x34", FormatLocation(loc, no_file_line).AsString());

  // File/line not shown and address exactly matches the symbol (the offset should be omitted).
  Location func_loc(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context, function);
  EXPECT_EQ("Func() + 0x34", FormatLocation(func_loc, no_file_line).AsString());

  // File/line-only location.
  EXPECT_EQ("0x1234 • /path/foo.cc:21",
            FormatLocation(Location(0x1234, FileLine("/path/foo.cc", 21), 0, symbol_context),
                           no_addrs_no_params)
                .AsString());

  // Full location.
  FormatLocationOptions always_addr;
  always_addr.always_show_addresses = true;
  always_addr.show_file_line = true;
  EXPECT_EQ("0x1234, Func() • /path/foo.cc:21", FormatLocation(loc, always_addr).AsString());
  EXPECT_EQ("Func() • /path/foo.cc:21", FormatLocation(loc, no_addrs_no_params).AsString());

  // Test with file shortening. This target has no files so everything is unique and will be
  // shortened.
  ProcessSymbolsTestSetup setup;
  FormatLocationOptions with_target;
  with_target.show_file_line = true;
  with_target.target_symbols = &setup.target();
  EXPECT_EQ("Func() • foo.cc:21", FormatLocation(loc, with_target).AsString());

  // Use the same parameters but force showing the whole path.
  with_target.show_file_path = true;
  EXPECT_EQ("Func() • /path/foo.cc:21", FormatLocation(loc, with_target).AsString());
}

TEST(FormatLocation, FormatLocation_ELF) {
  SymbolContext symbol_context = SymbolContext::ForRelativeAddresses();

  FormatLocationOptions options;
  options.always_show_addresses = false;

  // Address exactly at the beginning of the ELF symbol.
  constexpr uint64_t kFunctionAddress = 0x1000;
  fxl::RefPtr<ElfSymbol> elf_symbol(fxl::MakeRefCounted<ElfSymbol>(
      fxl::WeakPtr<ModuleSymbols>(),
      ElfSymbolRecord(ElfSymbolType::kPlt, kFunctionAddress, 0, "memset")));
  EXPECT_EQ(
      "$plt(memset)",
      FormatLocation(Location(kFunctionAddress, FileLine(), 0, symbol_context, elf_symbol), options)
          .AsString());

  // Address with an offset from the beginning.
  EXPECT_EQ("$plt(memset) + 0x6",
            FormatLocation(
                Location(kFunctionAddress + 6, FileLine(), 0, symbol_context, elf_symbol), options)
                .AsString());
}

// This implicitly tests FormatFileName() also.
TEST(FormatLocation, FormatFileLine) {
  FileLine fl("/path/to/foo.cc", 21);
  EXPECT_EQ("/path/to/foo.cc:21", FormatFileLine(fl).AsString());

  // Missing both.
  EXPECT_EQ("?:?", FormatFileLine(FileLine()).AsString());

  // Pass an TargetSymbols to trigger path shortening. Since the TargetSymbols has no files to
  // match, the name will be unique and we'll get just the name part.
  //
  // This also tests the syntax highlighting.
  ProcessSymbolsTestSetup setup;
  EXPECT_EQ("kFileName \"foo.cc\", kComment \":\", kNormal \"21\"",
            FormatFileLine(fl, &setup.target()).GetDebugString());
}

}  // namespace zxdb
