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

#include "src/developer/debug/zxdb/expr/found_name.h"
#include "src/developer/debug/zxdb/expr/parsed_identifier.h"
#include "src/developer/debug/zxdb/symbols/process_symbols.h"

namespace zxdb {

namespace {

// Returns true if the identifier is a special name that's understood by the symbol system but
// which won't be in the index.
//
// Currently these are PLT breakpoints (called "$plt(foo)" for the function "foo"), and the
// entrypoint (called "$main").
bool IsSpecialSymbolName(const Identifier& ident) {
  return ident.components().size() == 1u &&
         ident.components()[0].special() != SpecialIdentifier::kNone;
}

}  // namespace

std::vector<InputLocation> ExpandPermissiveInputLocationNames(
    const FindNameContext& context, const std::vector<InputLocation>& input) {
  // Currently all users of this API need the same set of options. This can be moved to a parameter
  // of this function if needed.
  FindNameOptions opts(FindNameOptions::kNoKinds);
  opts.max_results = FindNameOptions::kAllResults;
  opts.search_mode = FindNameOptions::kAllNamespaces;
  opts.find_functions = true;
  opts.find_vars = true;

  std::vector<InputLocation> result;

  std::vector<FoundName> found;  // Keep outside to avoid reallocation.
  for (const auto& in : input) {
    if (in.type == InputLocation::Type::kName) {
      // Needs expansion.
      found.clear();

      if (IsSpecialSymbolName(in.name)) {
        // Pass special names through, don't look in the index because they won't be there.
        result.push_back(in);
      } else {
        FindName(context, opts, ToParsedIdentifier(in.name), &found);
        for (const auto& f : found)
          result.emplace_back(ToIdentifier(f.GetName()));
      }
    } else {
      // Not a symbolic name, the output is the same as the input.
      result.push_back(in);
    }
  }
  return result;
}

// An alternate implementation of this function could get the actual symbol objects from the
// FindName results (function, variable), and then do a symbol lookup on that to get the full
// InputLocation. Basically InputLocation would have another "symbol object" mode that would take
// a RefPtr<Symbol> to look up.
//
// The advantage of that implementation is that it saves the symbol name lookup when we go to the
// ResolveInputLocation() call. Not round-tripping through names also helps remove some potential
// ambiguity about what we're referring to if there are multiple matches.
//
// The disadvantage is that the implementation is more complicated, especially since symbol objects
// don't currently have any ModuleSymbol information associated with them.
//
// TODO(bug 37608) Revisit this design when symbols know their modules. This might make the above
// design more desirable.
std::vector<Location> ResolvePermissiveInputLocations(const ProcessSymbols* process_symbols,
                                                      const ResolveOptions& resolve_options,
                                                      const FindNameContext& context,
                                                      const std::vector<InputLocation>& input) {
  std::vector<Location> result;
  for (const auto& in : ExpandPermissiveInputLocationNames(context, input)) {
    std::vector<Location> inner_result = process_symbols->ResolveInputLocation(in, resolve_options);
    result.insert(result.end(), inner_result.begin(), inner_result.end());
  }
  return result;
}

}  // namespace zxdb
