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

#include <fs/pseudo-file.h>
#include <lib/fxl/strings/string_printf.h>
#include <algorithm>
#include "debug_info_retriever.h"

using fxl::StringPrintf;

namespace component {

DebugDirectory::ProcessThreads::ProcessThreads(const zx::process* process)
    : ExposedObject("threads"), process_(process) {
  auto all_dir = component::ObjectDir::Make("all");
  all_dir.set_prop("stacks", [this]() -> std::string {
    return StringPrintf("\n%s", DebugInfoRetriever::GetInfo(process_).data());
  });

  object_dir().set_child(all_dir.object());
  object_dir().set_children_callback(
      [this](component::Object::ObjectVector* out_children) {
        fbl::Vector<ThreadInfo> threads;
        threads.reserve(kMaxThreads);
        GetThreads(&threads);

        for (const auto& thread : threads) {
          auto koid_string = StringPrintf("%lu", thread.koid);
          auto thread_obj = component::ObjectDir::Make(koid_string);
          auto koid = thread.koid;
          thread_obj.set_prop("stack", [this, koid]() -> std::string {
            zx_koid_t koids[] = {koid};
            return StringPrintf(
                "\n%s", DebugInfoRetriever::GetInfo(process_, koids, 1).data());
          });
          thread_obj.set_prop("koid", koid_string);
          thread_obj.set_prop("name", thread.name.data());
          out_children->push_back(thread_obj.object());
        }
      });
}

void DebugDirectory::ProcessThreads::GetThreads(fbl::Vector<ThreadInfo>* out) {
  zx_koid_t thread_ids[kMaxThreads];
  size_t num_ids;
  if (process_->get_info(ZX_INFO_PROCESS_THREADS, thread_ids,
                         sizeof(zx_koid_t) * kMaxThreads, &num_ids,
                         nullptr) != ZX_OK) {
    return;
  }

  for (size_t i = 0; i < num_ids; i++) {
    zx::thread t;
    char name[ZX_MAX_NAME_LEN];
    if (process_->get_child(thread_ids[i], ZX_RIGHT_SAME_RIGHTS, &t) != ZX_OK) {
      return;
    }
    if (t.get_property(ZX_PROP_NAME, &name, ZX_MAX_NAME_LEN) != ZX_OK) {
      return;
    }
    t.get_property(ZX_PROP_NAME, &name, ZX_MAX_NAME_LEN);
    out->push_back({thread_ids[i], name, std::move(t)});
  }
}

}  // namespace component
