// 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 "garnet/bin/zxdb/symbols/system_symbols.h"

#include "garnet/bin/zxdb/common/file_util.h"
#include "garnet/bin/zxdb/common/host_util.h"
#include "garnet/bin/zxdb/symbols/module_symbols_impl.h"
#include "garnet/public/lib/fxl/strings/string_printf.h"

namespace zxdb {

namespace {

// TODO(brettw) this is hardcoded and will only work in a full local build.
// We will need a more flexible way to do handle this, and also a way to
// explicitly specify a location for the mapping file.
std::string GetBuildDir() {
  // Expect the debugger to be in "<build>/host_x64/zxdb" and the build dir
  // to be one directory up.
  std::string path = GetSelfPath();
  if (path.empty())
    return path;

  // Trim off the last two slash-separated components ("host_x64/zxdb").
  size_t last_slash = path.rfind('/');
  if (last_slash != std::string::npos) {
    path.resize(last_slash);
    last_slash = path.rfind('/');
    if (last_slash != std::string::npos)
      path.resize(last_slash + 1);  // + 1 means keep the last slash.
  }
  return path;
}

}  // namespace

// SystemSymbols::ModuleRef ----------------------------------------------------

SystemSymbols::ModuleRef::ModuleRef(
    SystemSymbols* system_symbols,
    std::unique_ptr<ModuleSymbols> module_symbols)
    : system_symbols_(system_symbols),
      module_symbols_(std::move(module_symbols)) {}

SystemSymbols::ModuleRef::~ModuleRef() {
  if (system_symbols_)
    system_symbols_->WillDeleteModule(this);
}

void SystemSymbols::ModuleRef::SystemSymbolsDeleting() {
  system_symbols_ = nullptr;
}

// SystemSymbols ---------------------------------------------------------------

SystemSymbols::SystemSymbols() : build_dir_(GetBuildDir()) {
  // Add the system build ID file to the index. This will only exist in this
  // location when running in-tree.
  build_id_index_.AddBuildIDMappingFile(
      CatPathComponents(build_dir_, "ids.txt"));
}

SystemSymbols::~SystemSymbols() {
  // Disown any remaining ModuleRefs so they don't call us back.
  for (auto& pair : modules_)
    pair.second->SystemSymbolsDeleting();
  modules_.clear();
}

fxl::RefPtr<SystemSymbols::ModuleRef> SystemSymbols::InjectModuleForTesting(
    const std::string& build_id, std::unique_ptr<ModuleSymbols> module) {
  // Can't inject a module that already exists.
  FXL_DCHECK(modules_.find(build_id) == modules_.end());

  fxl::RefPtr<ModuleRef> result =
      fxl::MakeRefCounted<ModuleRef>(this, std::move(module));
  modules_[build_id] = result.get();
  return result;
}

Err SystemSymbols::GetModule(const std::string& name_for_msg,
                             const std::string& build_id,
                             fxl::RefPtr<ModuleRef>* module) {
  auto found_existing = modules_.find(build_id);
  if (found_existing != modules_.end()) {
    *module = fxl::RefPtr<ModuleRef>(found_existing->second);
    return Err();
  }

  std::string file_name = build_id_index_.FileForBuildID(build_id);
  if (file_name.empty()) {
    return Err(fxl::StringPrintf(
        "Could not load symbols for \"%s\" because there was no mapping for "
        "build ID \"%s\".",
        name_for_msg.c_str(), build_id.c_str()));
  }

  auto module_symbols =
      std::make_unique<ModuleSymbolsImpl>(file_name, build_id);
  Err err = module_symbols->Load();
  if (err.has_error())
    return err;

  *module = fxl::MakeRefCounted<ModuleRef>(this, std::move(module_symbols));
  modules_[build_id] = module->get();
  return Err();
}

void SystemSymbols::WillDeleteModule(ModuleRef* module) {
  // We expect relatively few total modules and removing them is also uncommon,
  // so this is a brute-force search.
  for (auto iter = modules_.begin(); iter != modules_.end(); ++iter) {
    if (iter->second == module) {
      modules_.erase(iter);
      return;
    }
  }
  FXL_NOTREACHED();  // Notified for unknown ModuleRef.
}

}  // namespace zxdb
