// Copyright 2018 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/symbols/system_symbols.h"

#include <memory>

#include "src/developer/debug/zxdb/common/file_util.h"
#include "src/developer/debug/zxdb/common/host_util.h"
#include "src/developer/debug/zxdb/common/ref_ptr_to.h"
#include "src/developer/debug/zxdb/symbols/dwarf_binary_impl.h"
#include "src/developer/debug/zxdb/symbols/module_symbols_impl.h"
#include "src/lib/elflib/elflib.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

// Checks for a file with the given name on the local system that has the given build ID. If
// it exists, it will return nonempty paths in the Entry, identical to
// BuildIDIndex::EntryForBuildID().
BuildIDIndex::Entry LoadLocalModuleSymbols(const std::string& name, const std::string& build_id) {
  BuildIDIndex::Entry result;

  if (name.empty() || name[0] != '/')
    return result;  // Only try local symbols when an absolute path is given.

  auto elf = elflib::ElfLib::Create(name);
  if (!elf)
    return result;

  std::string file_build_id = elf->GetGNUBuildID();
  if (file_build_id == build_id) {
    // Matches, declare this local file contains both code and symbols.
    result.debug_info = name;
    result.binary = name;
  }
  return result;
}

}  // namespace

SystemSymbols::SystemSymbols(DownloadHandler* download_handler)
    : download_handler_(download_handler), weak_factory_(this) {}

SystemSymbols::~SystemSymbols() = default;

void SystemSymbols::InjectModuleForTesting(const std::string& build_id, ModuleSymbols* module) {
  SaveModule(build_id, module);
}

Err SystemSymbols::GetModule(const std::string& name, const std::string& build_id,
                             fxl::RefPtr<ModuleSymbols>* module,
                             SystemSymbols::DownloadType download_type) {
  *module = fxl::RefPtr<ModuleSymbols>();

  auto found_existing = modules_.find(build_id);
  if (found_existing != modules_.end()) {
    *module = RefPtrTo(found_existing->second);
    return Err();
  }

  auto entry = build_id_index_.EntryForBuildID(build_id);

  if (enable_local_fallback_ && entry.debug_info.empty()) {
    // Local fallback is enabled and the name could be an absolute local path. See if the binary
    // matches and has symbols (this will leave entry.debug_info empty if still not found).
    entry = LoadLocalModuleSymbols(name, build_id);
  }

  if (entry.debug_info.empty() && download_type == SystemSymbols::DownloadType::kSymbols &&
      download_handler_) {
    download_handler_->RequestDownload(build_id, DebugSymbolFileType::kDebugInfo, false);
  }

  if (auto debug = elflib::ElfLib::Create(entry.debug_info)) {
    if (!debug->ProbeHasProgramBits() && entry.binary.empty() &&
        download_type == SystemSymbols::DownloadType::kBinary && download_handler_) {
      // File doesn't exist or has no symbols, schedule a download.
      download_handler_->RequestDownload(build_id, DebugSymbolFileType::kBinary, false);
    }
  }

  if (entry.debug_info.empty())
    return Err();  // No symbols synchronously available.

  auto binary = std::make_unique<DwarfBinaryImpl>(entry.debug_info, entry.binary, build_id);
  if (Err err = binary->Load(); err.has_error())
    return err;  // Symbols corrupt.

  *module =
      fxl::MakeRefCounted<ModuleSymbolsImpl>(std::move(binary), entry.build_dir, create_index_);

  SaveModule(build_id, module->get());  // Save in cache for future use.
  return Err();
}

void SystemSymbols::SaveModule(const std::string& build_id, ModuleSymbols* module) {
  // Can't save a module that already exists.
  FX_DCHECK(modules_.find(build_id) == modules_.end());

  module->set_deletion_cb(
      [weak_system = weak_factory_.GetWeakPtr(), build_id](ModuleSymbols* module) {
        if (!weak_system)
          return;
        SystemSymbols* system = weak_system.get();

        auto found = system->modules_.find(build_id);
        if (found == system->modules_.end()) {
          FX_NOTREACHED();  // Should be found if we registered.
          return;
        }

        FX_DCHECK(module == found->second);  // Mapping should match.
        system->modules_.erase(found);
      });
  modules_[build_id] = module;
}

}  // namespace zxdb
