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

#include "lldb/Core/PluginManager.h"
#include "lldb/Interpreter/OptionValueString.h"
#include "lldb/Utility/Args.h"
#include "lldb/Utility/LLDBLog.h"
#include "lldb/Utility/Log.h"

#include "llvm/Debuginfod/Debuginfod.h"
#include "llvm/Debuginfod/HTTPClient.h"

using namespace lldb;
using namespace lldb_private;

LLDB_PLUGIN_DEFINE(SymbolLocatorDebuginfod)

namespace {

#define LLDB_PROPERTIES_symbollocatordebuginfod
#include "SymbolLocatorDebuginfodProperties.inc"

enum {
#define LLDB_PROPERTIES_symbollocatordebuginfod
#include "SymbolLocatorDebuginfodPropertiesEnum.inc"
};

class PluginProperties : public Properties {
public:
  static llvm::StringRef GetSettingName() {
    return SymbolLocatorDebuginfod::GetPluginNameStatic();
  }

  PluginProperties() {
    m_collection_sp = std::make_shared<OptionValueProperties>(GetSettingName());
    m_collection_sp->Initialize(g_symbollocatordebuginfod_properties);

    // We need to read the default value first to read the environment variable.
    llvm::SmallVector<llvm::StringRef> urls = llvm::getDefaultDebuginfodUrls();
    Args arg_urls{urls};
    m_collection_sp->SetPropertyAtIndexFromArgs(ePropertyServerURLs, arg_urls);

    m_collection_sp->SetValueChangedCallback(
        ePropertyServerURLs, [this] { ServerURLsChangedCallback(); });
  }

  Args GetDebugInfoDURLs() const {
    Args urls;
    m_collection_sp->GetPropertyAtIndexAsArgs(ePropertyServerURLs, urls);
    return urls;
  }

  llvm::Expected<std::string> GetCachePath() {
    OptionValueString *s =
        m_collection_sp->GetPropertyAtIndexAsOptionValueString(
            ePropertySymbolCachePath);
    // If we don't have a valid cache location, use the default one.
    if (!s || !s->GetCurrentValueAsRef().size()) {
      llvm::Expected<std::string> maybeCachePath =
          llvm::getDefaultDebuginfodCacheDirectory();
      if (!maybeCachePath)
        return maybeCachePath;
      return *maybeCachePath;
    }
    return s->GetCurrentValue();
  }

  std::chrono::milliseconds GetTimeout() const {
    std::optional<uint64_t> seconds =
        m_collection_sp->GetPropertyAtIndexAs<uint64_t>(ePropertyTimeout);
    if (seconds && *seconds != 0) {
      return std::chrono::duration_cast<std::chrono::milliseconds>(
          std::chrono::seconds(*seconds));
    } else {
      return llvm::getDefaultDebuginfodTimeout();
    }
  }

private:
  void ServerURLsChangedCallback() {
    m_server_urls = GetDebugInfoDURLs();
    llvm::SmallVector<llvm::StringRef> dbginfod_urls;
    llvm::for_each(m_server_urls, [&](const auto &obj) {
      dbginfod_urls.push_back(obj.ref());
    });
    llvm::setDefaultDebuginfodUrls(dbginfod_urls);
  }
  // Storage for the StringRef's used within the Debuginfod library.
  Args m_server_urls;
};

} // namespace

static PluginProperties &GetGlobalPluginProperties() {
  static PluginProperties g_settings;
  return g_settings;
}

SymbolLocatorDebuginfod::SymbolLocatorDebuginfod() : SymbolLocator() {}

void SymbolLocatorDebuginfod::Initialize() {
  static llvm::once_flag g_once_flag;

  llvm::call_once(g_once_flag, []() {
    PluginManager::RegisterPlugin(
        GetPluginNameStatic(), GetPluginDescriptionStatic(), CreateInstance,
        LocateExecutableObjectFile, LocateExecutableSymbolFile, nullptr,
        nullptr, SymbolLocatorDebuginfod::DebuggerInitialize);
    llvm::HTTPClient::initialize();
  });
}

void SymbolLocatorDebuginfod::DebuggerInitialize(Debugger &debugger) {
  if (!PluginManager::GetSettingForSymbolLocatorPlugin(
          debugger, PluginProperties::GetSettingName())) {
    const bool is_global_setting = true;
    PluginManager::CreateSettingForSymbolLocatorPlugin(
        debugger, GetGlobalPluginProperties().GetValueProperties(),
        "Properties for the Debuginfod Symbol Locator plug-in.",
        is_global_setting);
  }
}

void SymbolLocatorDebuginfod::Terminate() {
  PluginManager::UnregisterPlugin(CreateInstance);
  llvm::HTTPClient::cleanup();
}

llvm::StringRef SymbolLocatorDebuginfod::GetPluginDescriptionStatic() {
  return "Debuginfod symbol locator.";
}

SymbolLocator *SymbolLocatorDebuginfod::CreateInstance() {
  return new SymbolLocatorDebuginfod();
}

static llvm::StringRef getFileName(const ModuleSpec &module_spec,
                                   std::string url_path) {
  // Check if the URL path requests an executable file or a symbol file
  bool is_executable = url_path.find("debuginfo") == std::string::npos;
  if (is_executable)
    return module_spec.GetFileSpec().GetFilename().GetStringRef();
  llvm::StringRef symbol_file =
      module_spec.GetSymbolFileSpec().GetFilename().GetStringRef();
  // Remove llvmcache- prefix and hash, keep origin file name
  if (symbol_file.starts_with("llvmcache-")) {
    size_t pos = symbol_file.rfind('-');
    if (pos != llvm::StringRef::npos) {
      symbol_file = symbol_file.substr(pos + 1);
    }
  }
  return symbol_file;
}

static std::optional<FileSpec>
GetFileForModule(const ModuleSpec &module_spec,
                 std::function<std::string(llvm::object::BuildID)> UrlBuilder) {
  const UUID &module_uuid = module_spec.GetUUID();
  // Don't bother if we don't have a valid UUID, Debuginfod isn't available,
  // or if the 'symbols.enable-external-lookup' setting is false.
  if (!module_uuid.IsValid() || !llvm::canUseDebuginfod() ||
      !ModuleList::GetGlobalModuleListProperties().GetEnableExternalLookup())
    return {};

  // Grab LLDB's Debuginfod overrides from the
  // plugin.symbol-locator.debuginfod.* settings.
  PluginProperties &plugin_props = GetGlobalPluginProperties();
  llvm::Expected<std::string> cache_path_or_err = plugin_props.GetCachePath();
  // A cache location is *required*.
  if (!cache_path_or_err)
    return {};
  std::string cache_path = *cache_path_or_err;
  llvm::SmallVector<llvm::StringRef> debuginfod_urls =
      llvm::getDefaultDebuginfodUrls();
  std::chrono::milliseconds timeout = plugin_props.GetTimeout();

  // We're ready to ask the Debuginfod library to find our file.
  llvm::object::BuildID build_id(module_uuid.GetBytes());
  std::string url_path = UrlBuilder(build_id);
  llvm::StringRef file_name = getFileName(module_spec, url_path);
  std::string cache_file_name = llvm::toHex(build_id, true);
  if (!file_name.empty())
    cache_file_name += "-" + file_name.str();
  llvm::Expected<std::string> result = llvm::getCachedOrDownloadArtifact(
      cache_file_name, url_path, cache_path, debuginfod_urls, timeout);
  if (result)
    return FileSpec(*result);

  Log *log = GetLog(LLDBLog::Symbols);
  auto err_message = llvm::toString(result.takeError());
  LLDB_LOGV(log,
            "Debuginfod failed to download symbol artifact {0} with error {1}",
            url_path, err_message);
  return {};
}

std::optional<ModuleSpec> SymbolLocatorDebuginfod::LocateExecutableObjectFile(
    const ModuleSpec &module_spec) {
  return GetFileForModule(module_spec, llvm::getDebuginfodExecutableUrlPath);
}

std::optional<FileSpec> SymbolLocatorDebuginfod::LocateExecutableSymbolFile(
    const ModuleSpec &module_spec, const FileSpecList &default_search_paths) {
  return GetFileForModule(module_spec, llvm::getDebuginfodDebuginfoUrlPath);
}
