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

#include <fcntl.h>
#include <fuchsia/boot/c/fidl.h>
#include <lib/fdio/directory.h>
#include <lib/fdio/fd.h>
#include <lib/fdio/fdio.h>
#include <zircon/syscalls/object.h>

#include "src/developer/debug/shared/zx_status.h"
#include "src/lib/files/file.h"
#include "src/lib/fxl/logging.h"

namespace debug_agent {

namespace {

template <typename ResultObject>
std::vector<ResultObject> GetChildObjects(const ObjectProvider& provider, zx_handle_t parent,
                                          uint32_t child_kind) {
  auto koids = provider.GetChildKoids(parent, child_kind);

  std::vector<ResultObject> result;
  result.reserve(koids.size());

  for (zx_koid_t koid : koids) {
    zx_handle_t handle;
    if (zx_object_get_child(parent, koid, ZX_RIGHT_SAME_RIGHTS, &handle) == ZX_OK)
      result.push_back(ResultObject(handle));
  }
  return result;
}

// Searches the process tree rooted at "job" for a process with the given
// koid. If found, puts it in *out* and returns true.
bool FindProcess(const ObjectProvider& provider, const zx::job& job, zx_koid_t search_for,
                 zx::process* out) {
  for (auto& proc : provider.GetChildProcesses(job.get())) {
    if (provider.KoidForObject(proc) == search_for) {
      *out = std::move(proc);
      return true;
    }
  }

  for (const auto& job : provider.GetChildJobs(job.get())) {
    if (FindProcess(provider, job, search_for, out))
      return true;
  }
  return false;
}

// Searches root job for a job with the given
// koid. If found, puts it in *out* and returns true.
bool FindJob(const ObjectProvider& provider, zx::job root_job, zx_koid_t search_for, zx::job* out) {
  if (provider.KoidForObject(root_job) == search_for) {
    out->reset(root_job.release());
    return true;
  }

  auto child_jobs = provider.GetChildJobs(root_job.get());
  for (auto& child_job : child_jobs) {
    if (FindJob(provider, zx::job(child_job.release()), search_for, out))
      return true;
  }
  return false;
}

}  // namespace

ObjectProvider::ObjectProvider() = default;
ObjectProvider::~ObjectProvider() = default;

zx::thread ObjectProvider::ThreadForKoid(zx_handle_t process, zx_koid_t thread_koid) const {
  zx_handle_t thread_handle = ZX_HANDLE_INVALID;
  if (zx_object_get_child(process, thread_koid, ZX_RIGHT_SAME_RIGHTS, &thread_handle) != ZX_OK)
    return zx::thread();
  return zx::thread(thread_handle);
}

zx_koid_t ObjectProvider::KoidForObject(zx_handle_t object) const {
  zx_info_handle_basic_t info;
  if (zx_object_get_info(object, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr) !=
      ZX_OK)
    return 0;
  return info.koid;
}

std::string ObjectProvider::NameForObject(zx_handle_t object) const {
  char name[ZX_MAX_NAME_LEN];
  if (zx_object_get_property(object, ZX_PROP_NAME, name, sizeof(name)) == ZX_OK)
    return std::string(name);
  return std::string();
}

std::vector<zx_koid_t> ObjectProvider::GetChildKoids(zx_handle_t parent,
                                                     uint32_t child_kind) const {
  constexpr size_t kNumExtraKoids = 10u;

  size_t actual = 0;
  size_t available = 0;
  std::vector<zx_koid_t> result;

  // This is inherently racy, but we retry once with a bit of slop to try to
  // get a complete list.
  for (int pass = 0; pass < 2; pass++) {
    if (actual < available)
      result.resize(available + kNumExtraKoids);
    zx_status_t status = zx_object_get_info(parent, child_kind, result.data(),
                                            result.size() * sizeof(zx_koid_t), &actual, &available);
    if (status != ZX_OK || actual == available)
      break;
  }
  result.resize(actual);
  return result;
}

zx_status_t ObjectProvider::GetChild(zx_handle_t parent, zx_koid_t koid, uint32_t rights,
                                     zx_handle_t* child) const {
  return zx_object_get_child(parent, koid, ZX_RIGHT_SAME_RIGHTS, child);
}

std::vector<zx::job> ObjectProvider::GetChildJobs(zx_handle_t job) const {
  return GetChildObjects<zx::job>(*this, job, ZX_INFO_JOB_CHILDREN);
}

std::vector<zx::process> ObjectProvider::GetChildProcesses(zx_handle_t job) const {
  return GetChildObjects<zx::process>(*this, job, ZX_INFO_JOB_PROCESSES);
}

std::vector<zx::thread> ObjectProvider::GetChildThreads(zx_handle_t process) const {
  return GetChildObjects<zx::thread>(*this, process, ZX_INFO_PROCESS_THREADS);
}

zx::process ObjectProvider::GetProcessFromException(zx_handle_t exception) const {
  zx_handle_t process_handle = ZX_HANDLE_INVALID;
  zx_status_t status = zx_exception_get_process(exception, &process_handle);
  FXL_DCHECK(status == ZX_OK) << "Got: " << debug_ipc::ZxStatusToString(status);

  return zx::process(process_handle);
}

zx::thread ObjectProvider::GetThreadFromException(zx_handle_t exception) const {
  zx_handle_t thread_handle = ZX_HANDLE_INVALID;
  zx_status_t status = zx_exception_get_thread(exception, &thread_handle);
  FXL_DCHECK(status == ZX_OK) << "Got: " << debug_ipc::ZxStatusToString(status);

  return zx::thread(thread_handle);
}

zx::process ObjectProvider::GetProcessFromKoid(zx_koid_t koid) const {
  zx::process result;
  FindProcess(*this, GetRootJob(), koid, &result);
  return result;
}

zx::job ObjectProvider::GetJobFromKoid(zx_koid_t koid) const {
  zx::job result;
  FindJob(*this, GetRootJob(), koid, &result);
  return result;
}

zx_koid_t ObjectProvider::GetRootJobKoid() const { return KoidForObject(GetRootJob()); }

// The hub writes the job it uses to create components in a special file.
//
// This is note quite correct. This code actually returns the job that contains
// the debug agent itself, which is usually the right thing because the debug
// agent normally runs in the component root.
//
// TODO: Find the correct job even when the debug agent is run from elsewhere.
zx_koid_t ObjectProvider::GetComponentJobKoid() const {
  std::string koid_str;
  bool file_read = files::ReadFileToString("/hub/job-id", &koid_str);
  if (!file_read) {
    FXL_LOG(ERROR) << "Not able to read job-id: " << strerror(errno);
    return 0;
  }

  char* end = NULL;
  uint64_t koid = strtoul(koid_str.c_str(), &end, 10);
  if (*end) {
    FXL_LOG(ERROR) << "Invalid job-id: " << koid_str.c_str();
    return 0;
  }

  return koid;
}

// TODO(brettw) this is based on the code in Zircon's task-utils which uses
// this hack to get the root job handle. It will likely need to be updated
// when a better way to get the root job is found.
zx::job ObjectProvider::GetRootJob() const {
  int fd = open("/svc/fuchsia.boot.RootJob", O_RDWR);
  if (fd < 0) {
    FXL_NOTREACHED();
    return zx::job();
  }

  zx::channel channel;
  zx_status_t status = fdio_get_service_handle(fd, channel.reset_and_get_address());
  if (status != ZX_OK) {
    FXL_NOTREACHED();
    return zx::job();
  }

  zx_handle_t root_job;
  zx_status_t fidl_status = fuchsia_boot_RootJobGet(channel.get(), &root_job);
  if (fidl_status != ZX_OK) {
    FXL_NOTREACHED();
    return zx::job();
  }
  return zx::job(root_job);
}

zx_status_t ObjectProvider::ListHandleRights(zx_handle_t handle, std::string* out) const {
  zx_info_handle_basic info;
  zx_status_t status =
      zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  if (status != ZX_OK)
    return status;

  // clang-format off
  std::stringstream ss;
  if (info.rights & ZX_RIGHT_DUPLICATE) { ss << "ZX_RIGHT_DUPLICATE" << std::endl; }
  if (info.rights & ZX_RIGHT_TRANSFER) { ss << "ZX_RIGHT_TRANSFER" << std::endl; }
  if (info.rights & ZX_RIGHT_READ) { ss << "ZX_RIGHT_READ" << std::endl; }
  if (info.rights & ZX_RIGHT_WRITE) { ss << "ZX_RIGHT_WRITE" << std::endl; }
  if (info.rights & ZX_RIGHT_EXECUTE) { ss << "ZX_RIGHT_EXECUTE" << std::endl; }
  if (info.rights & ZX_RIGHT_MAP) { ss << "ZX_RIGHT_MAP" << std::endl; }
  if (info.rights & ZX_RIGHT_GET_PROPERTY) { ss << "ZX_RIGHT_GET_PROPERTY" << std::endl; }
  if (info.rights & ZX_RIGHT_SET_PROPERTY) { ss << "ZX_RIGHT_SET_PROPERTY" << std::endl; }
  if (info.rights & ZX_RIGHT_ENUMERATE) { ss << "ZX_RIGHT_ENUMERATE" << std::endl; }
  if (info.rights & ZX_RIGHT_DESTROY) { ss << "ZX_RIGHT_DESTROY" << std::endl; }
  if (info.rights & ZX_RIGHT_SET_POLICY) { ss << "ZX_RIGHT_SET_POLICY" << std::endl; }
  if (info.rights & ZX_RIGHT_GET_POLICY) { ss << "ZX_RIGHT_GET_POLICY" << std::endl; }
  if (info.rights & ZX_RIGHT_SIGNAL) { ss << "ZX_RIGHT_SIGNAL" << std::endl; }
  if (info.rights & ZX_RIGHT_SIGNAL_PEER) { ss << "ZX_RIGHT_SIGNAL_PEER" << std::endl; }
  if (info.rights & ZX_RIGHT_WAIT) { ss << "ZX_RIGHT_WAIT" << std::endl; }
  if (info.rights & ZX_RIGHT_INSPECT) { ss << "ZX_RIGHT_INSPECT" << std::endl; }
  if (info.rights & ZX_RIGHT_MANAGE_JOB) { ss << "ZX_RIGHT_MANAGE_JOB" << std::endl; }
  if (info.rights & ZX_RIGHT_MANAGE_PROCESS) { ss << "ZX_RIGHT_MANAGE_PROCESS" << std::endl; }
  if (info.rights & ZX_RIGHT_MANAGE_THREAD) { ss << "ZX_RIGHT_MANAGE_THREAD" << std::endl; }
  if (info.rights & ZX_RIGHT_APPLY_PROFILE) { ss << "ZX_RIGHT_APPLY_PROFILE" << std::endl; }
  if (info.rights & ZX_RIGHT_SAME_RIGHTS) { ss << "ZX_RIGHT_SAME_RIGHTS" << std::endl; }
  // clang-format on

  *out = ss.str();
  return ZX_OK;
}

}  // namespace debug_agent
