//===-- BreakpointResolverName.cpp ----------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "lldb/Breakpoint/BreakpointResolverName.h"

#include "lldb/Breakpoint/BreakpointLocation.h"
#include "lldb/Core/Architecture.h"
#include "lldb/Core/Module.h"
#include "lldb/Symbol/Block.h"
#include "lldb/Symbol/Function.h"
#include "lldb/Symbol/Symbol.h"
#include "lldb/Symbol/SymbolContext.h"
#include "lldb/Target/Language.h"
#include "lldb/Target/Target.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"
#include "lldb/Utility/StreamString.h"

using namespace lldb;
using namespace lldb_private;

BreakpointResolverName::BreakpointResolverName(
    const BreakpointSP &bkpt, const char *name_cstr,
    FunctionNameType name_type_mask, LanguageType language,
    Breakpoint::MatchType type, lldb::addr_t offset, bool offset_is_insn_count,
    bool skip_prologue)
    : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset,
                         offset_is_insn_count),
      m_match_type(type), m_language(language), m_skip_prologue(skip_prologue) {
  if (m_match_type == Breakpoint::Regexp) {
    m_regex = RegularExpression(name_cstr);
    if (!m_regex.IsValid()) {
      Log *log = GetLog(LLDBLog::Breakpoints);

      LLDB_LOGF(log, "warning: function name regexp: \"%s\" did not compile.",
                name_cstr);
    }
  } else {
    AddNameLookup(name_cstr, name_type_mask);
  }
}

BreakpointResolverName::BreakpointResolverName(
    const BreakpointSP &bkpt, const char *names[], size_t num_names,
    FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
    bool skip_prologue)
    : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
      m_match_type(Breakpoint::Exact), m_language(language),
      m_skip_prologue(skip_prologue) {
  for (size_t i = 0; i < num_names; i++) {
    AddNameLookup(names[i], name_type_mask);
  }
}

BreakpointResolverName::BreakpointResolverName(
    const BreakpointSP &bkpt, const std::vector<std::string> &names,
    FunctionNameType name_type_mask, LanguageType language, lldb::addr_t offset,
    bool skip_prologue)
    : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
      m_match_type(Breakpoint::Exact), m_language(language),
      m_skip_prologue(skip_prologue) {
  for (const std::string &name : names) {
    AddNameLookup(name, name_type_mask);
  }
}

BreakpointResolverName::BreakpointResolverName(const BreakpointSP &bkpt,
                                               RegularExpression func_regex,
                                               lldb::LanguageType language,
                                               lldb::addr_t offset,
                                               bool skip_prologue)
    : BreakpointResolver(bkpt, BreakpointResolver::NameResolver, offset),
      m_regex(std::move(func_regex)), m_match_type(Breakpoint::Regexp),
      m_language(language), m_skip_prologue(skip_prologue) {}

BreakpointResolverName::BreakpointResolverName(
    const BreakpointResolverName &rhs)
    : BreakpointResolver(rhs.GetBreakpoint(), BreakpointResolver::NameResolver,
                         rhs.GetOffset(), rhs.GetOffsetIsInsnCount()),
      m_lookups(rhs.m_lookups), m_regex(rhs.m_regex),
      m_match_type(rhs.m_match_type), m_language(rhs.m_language),
      m_skip_prologue(rhs.m_skip_prologue) {}

BreakpointResolverSP BreakpointResolverName::CreateFromStructuredData(
    const StructuredData::Dictionary &options_dict, Status &error) {
  LanguageType language = eLanguageTypeUnknown;
  llvm::StringRef language_name;
  bool success = options_dict.GetValueForKeyAsString(
      GetKey(OptionNames::LanguageName), language_name);
  if (success) {
    language = Language::GetLanguageTypeFromString(language_name);
    if (language == eLanguageTypeUnknown) {
      error = Status::FromErrorStringWithFormatv(
          "BRN::CFSD: Unknown language: {0}.", language_name);
      return nullptr;
    }
  }

  lldb::offset_t offset = 0;
  success =
      options_dict.GetValueForKeyAsInteger(GetKey(OptionNames::Offset), offset);
  if (!success) {
    error = Status::FromErrorString("BRN::CFSD: Missing offset entry.");
    return nullptr;
  }

  bool skip_prologue;
  success = options_dict.GetValueForKeyAsBoolean(
      GetKey(OptionNames::SkipPrologue), skip_prologue);
  if (!success) {
    error = Status::FromErrorString("BRN::CFSD: Missing Skip prologue entry.");
    return nullptr;
  }

  llvm::StringRef regex_text;
  success = options_dict.GetValueForKeyAsString(
      GetKey(OptionNames::RegexString), regex_text);
  if (success) {
    return std::make_shared<BreakpointResolverName>(
        nullptr, RegularExpression(regex_text), language, offset,
        skip_prologue);
  }
  StructuredData::Array *names_array;
  success = options_dict.GetValueForKeyAsArray(
      GetKey(OptionNames::SymbolNameArray), names_array);
  if (!success) {
    error = Status::FromErrorString("BRN::CFSD: Missing symbol names entry.");
    return nullptr;
  }
    StructuredData::Array *names_mask_array;
    success = options_dict.GetValueForKeyAsArray(
        GetKey(OptionNames::NameMaskArray), names_mask_array);
    if (!success) {
      error = Status::FromErrorString(
          "BRN::CFSD: Missing symbol names mask entry.");
      return nullptr;
    }

    size_t num_elem = names_array->GetSize();
    if (num_elem != names_mask_array->GetSize()) {
      error = Status::FromErrorString(
          "BRN::CFSD: names and names mask arrays have different sizes.");
      return nullptr;
    }

    if (num_elem == 0) {
      error = Status::FromErrorString(
          "BRN::CFSD: no name entry in a breakpoint by name breakpoint.");
      return nullptr;
    }
    std::vector<std::string> names;
    std::vector<FunctionNameType> name_masks;
    for (size_t i = 0; i < num_elem; i++) {
      std::optional<llvm::StringRef> maybe_name =
          names_array->GetItemAtIndexAsString(i);
      if (!maybe_name) {
        error =
            Status::FromErrorString("BRN::CFSD: name entry is not a string.");
        return nullptr;
      }
      auto maybe_fnt = names_mask_array->GetItemAtIndexAsInteger<
          std::underlying_type<FunctionNameType>::type>(i);
      if (!maybe_fnt) {
        error = Status::FromErrorString(
            "BRN::CFSD: name mask entry is not an integer.");
        return nullptr;
      }
      names.push_back(std::string(*maybe_name));
      name_masks.push_back(static_cast<FunctionNameType>(*maybe_fnt));
    }

    std::shared_ptr<BreakpointResolverName> resolver_sp =
        std::make_shared<BreakpointResolverName>(
            nullptr, names[0].c_str(), name_masks[0], language,
            Breakpoint::MatchType::Exact, offset,
            /*offset_is_insn_count = */ false, skip_prologue);
    for (size_t i = 1; i < num_elem; i++) {
      resolver_sp->AddNameLookup(names[i], name_masks[i]);
    }
    return resolver_sp;
}

StructuredData::ObjectSP BreakpointResolverName::SerializeToStructuredData() {
  StructuredData::DictionarySP options_dict_sp(
      new StructuredData::Dictionary());

  if (m_regex.IsValid()) {
    options_dict_sp->AddStringItem(GetKey(OptionNames::RegexString),
                                   m_regex.GetText());
  } else {
    StructuredData::ArraySP names_sp(new StructuredData::Array());
    StructuredData::ArraySP name_masks_sp(new StructuredData::Array());
    for (auto lookup : m_lookups) {
      names_sp->AddItem(std::make_shared<StructuredData::String>(
          lookup.GetName().GetStringRef()));
      name_masks_sp->AddItem(std::make_shared<StructuredData::UnsignedInteger>(
          lookup.GetNameTypeMask()));
    }
    options_dict_sp->AddItem(GetKey(OptionNames::SymbolNameArray), names_sp);
    options_dict_sp->AddItem(GetKey(OptionNames::NameMaskArray), name_masks_sp);
  }
  if (m_language != eLanguageTypeUnknown)
    options_dict_sp->AddStringItem(
        GetKey(OptionNames::LanguageName),
        Language::GetNameForLanguageType(m_language));
  options_dict_sp->AddBooleanItem(GetKey(OptionNames::SkipPrologue),
                                  m_skip_prologue);

  return WrapOptionsDict(options_dict_sp);
}

void BreakpointResolverName::AddNameLookup(llvm::StringRef name,
                                           FunctionNameType name_type_mask) {
  std::vector<Module::LookupInfo> infos = Module::LookupInfo::MakeLookupInfos(
      ConstString(name), name_type_mask, m_language);
  llvm::append_range(m_lookups, infos);

  auto add_variant_funcs = [&](Language *lang) {
    for (Language::MethodNameVariant variant :
         lang->GetMethodNameVariants(name)) {
      // FIXME: Should we be adding variants that aren't of type Full?
      if (variant.GetType() & lldb::eFunctionNameTypeFull) {
        std::vector<Module::LookupInfo> variant_lookups =
            Module::LookupInfo::MakeLookupInfos(
                ConstString(name), variant.GetType(), lang->GetLanguageType(),
                ConstString(variant.GetName()));
        llvm::append_range(m_lookups, variant_lookups);
      }
    }
    return IterationAction::Continue;
  };

  if (Language *lang = Language::FindPlugin(m_language)) {
    add_variant_funcs(lang);
  } else {
    // Most likely m_language is eLanguageTypeUnknown. We check each language for
    // possible variants or more qualified names and create lookups for those as
    // well.
    Language::ForEach(add_variant_funcs);
  }
}

// FIXME: Right now we look at the module level, and call the module's
// "FindFunctions".
// Greg says he will add function tables, maybe at the CompileUnit level to
// accelerate function lookup.  At that point, we should switch the depth to
// CompileUnit, and look in these tables.

Searcher::CallbackReturn
BreakpointResolverName::SearchCallback(SearchFilter &filter,
                                       SymbolContext &context, Address *addr) {
  Log *log = GetLog(LLDBLog::Breakpoints);

  SymbolContextList func_list;
  bool filter_by_cu =
      (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
  bool filter_by_language = (m_language != eLanguageTypeUnknown);

  ModuleFunctionSearchOptions function_options;
  function_options.include_symbols = !filter_by_cu;
  function_options.include_inlines = true;

  switch (m_match_type) {
  case Breakpoint::Exact:
    if (context.module_sp) {
      for (const auto &lookup : m_lookups) {
        const size_t start_func_idx = func_list.GetSize();
        context.module_sp->FindFunctions(lookup, CompilerDeclContext(),
                                         function_options, func_list);

        const size_t end_func_idx = func_list.GetSize();

        if (start_func_idx < end_func_idx)
          lookup.Prune(func_list, start_func_idx);
      }
    }
    break;
  case Breakpoint::Regexp:
    if (context.module_sp) {
      context.module_sp->FindFunctions(m_regex, function_options, func_list);
    }
    break;
  case Breakpoint::Glob:
    LLDB_LOG(log, "warning: glob is not supported yet.");
    break;
  }

  // If the filter specifies a Compilation Unit, remove the ones that don't
  // pass at this point.
  if (filter_by_cu || filter_by_language) {
    uint32_t num_functions = func_list.GetSize();

    for (size_t idx = 0; idx < num_functions; idx++) {
      bool remove_it = false;
      SymbolContext sc;
      func_list.GetContextAtIndex(idx, sc);
      if (filter_by_cu) {
        if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
          remove_it = true;
      }

      if (filter_by_language) {
        LanguageType sym_language = sc.GetLanguage();
        if ((Language::GetPrimaryLanguage(sym_language) !=
             Language::GetPrimaryLanguage(m_language)) &&
            (sym_language != eLanguageTypeUnknown)) {
          remove_it = true;
        }
      }

      if (remove_it) {
        func_list.RemoveContextAtIndex(idx);
        num_functions--;
        idx--;
      }
    }
  }

  BreakpointSP breakpoint_sp = GetBreakpoint();
  Breakpoint &breakpoint = *breakpoint_sp;
  Address break_addr;

  // Remove any duplicates between the function list and the symbol list
  for (const SymbolContext &sc : func_list) {
    bool is_reexported = false;

    if (sc.block && sc.block->GetInlinedFunctionInfo()) {
      if (!sc.block->GetStartAddress(break_addr))
        break_addr.Clear();
    } else if (sc.function) {
      break_addr = sc.function->GetAddress();
      if (m_skip_prologue && break_addr.IsValid()) {
        const uint32_t prologue_byte_size = sc.function->GetPrologueByteSize();
        if (prologue_byte_size)
          break_addr.Slide(prologue_byte_size);
      }
    } else if (sc.symbol) {
      if (sc.symbol->GetType() == eSymbolTypeReExported) {
        const Symbol *actual_symbol =
            sc.symbol->ResolveReExportedSymbol(breakpoint.GetTarget());
        if (actual_symbol) {
          is_reexported = true;
          break_addr = actual_symbol->GetAddress();
        }
      } else {
        break_addr = sc.symbol->GetAddress();
      }

      if (m_skip_prologue && break_addr.IsValid()) {
        const uint32_t prologue_byte_size = sc.symbol->GetPrologueByteSize();
        if (prologue_byte_size)
          break_addr.Slide(prologue_byte_size);
        else {
          const Architecture *arch =
              breakpoint.GetTarget().GetArchitecturePlugin();
          if (arch)
            arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
        }
      }
    }

    if (!break_addr.IsValid())
      continue;

    if (!filter.AddressPasses(break_addr))
      continue;

    bool new_location;
    BreakpointLocationSP bp_loc_sp(AddLocation(break_addr, &new_location));
    bp_loc_sp->SetIsReExported(is_reexported);
    if (bp_loc_sp && new_location && !breakpoint.IsInternal()) {
      if (log) {
        StreamString s;
        bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
        LLDB_LOGF(log, "Added location: %s\n", s.GetData());
      }
    }
  }

  return Searcher::eCallbackReturnContinue;
}

lldb::SearchDepth BreakpointResolverName::GetDepth() {
  return lldb::eSearchDepthModule;
}

void BreakpointResolverName::GetDescription(Stream *s) {
  if (m_match_type == Breakpoint::Regexp)
    s->Printf("regex = '%s'", m_regex.GetText().str().c_str());
  else {
    // Since there may be many lookups objects for the same name breakpoint (one
    // per language available), unique them by name, and operate on those unique
    // names.
    std::vector<ConstString> unique_lookups;
    for (auto &lookup : m_lookups) {
      if (!llvm::is_contained(unique_lookups, lookup.GetName()))
        unique_lookups.push_back(lookup.GetName());
    }
    if (unique_lookups.size() == 1)
      s->Printf("name = '%s'", unique_lookups[0].GetCString());
    else {
      size_t num_names = unique_lookups.size();
      s->PutCString("names = {");
      for (size_t i = 0; i < num_names; i++) {
        s->Printf("%s'%s'", (i == 0 ? "" : ", "),
                  unique_lookups[i].GetCString());
      }
      s->PutCString("}");
    }
  }
  if (m_language != eLanguageTypeUnknown) {
    s->Printf(", language = %s", Language::GetNameForLanguageType(m_language));
  }
}

void BreakpointResolverName::Dump(Stream *s) const {}

lldb::BreakpointResolverSP
BreakpointResolverName::CopyForBreakpoint(BreakpointSP &breakpoint) {
  lldb::BreakpointResolverSP ret_sp(new BreakpointResolverName(*this));
  ret_sp->SetBreakpoint(breakpoint);
  return ret_sp;
}
