// 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/lib/debugger_utils/threads.h"

#include <algorithm>

#include "garnet/lib/debugger_utils/jobs.h"
#include "garnet/lib/debugger_utils/util.h"
#include "src/lib/fxl/logging.h"
#include "src/lib/fxl/strings/string_printf.h"

namespace debugger_utils {

uint32_t GetThreadOsState(zx_handle_t thread) {
  zx_info_thread_t info;
  zx_status_t status =
      zx_object_get_info(thread, ZX_INFO_THREAD, &info, sizeof(info), nullptr, nullptr);
  FXL_CHECK(status == ZX_OK) << status;
  return info.state;
}

uint32_t GetThreadOsState(const zx::thread& thread) { return GetThreadOsState(thread.get()); }

const char* ThreadOsStateName(uint32_t state) {
#define CASE_TO_STR(x) \
  case x:              \
    return #x
  switch (state) {
    CASE_TO_STR(ZX_THREAD_STATE_NEW);
    CASE_TO_STR(ZX_THREAD_STATE_RUNNING);
    CASE_TO_STR(ZX_THREAD_STATE_SUSPENDED);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED);
    CASE_TO_STR(ZX_THREAD_STATE_DYING);
    CASE_TO_STR(ZX_THREAD_STATE_DEAD);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_EXCEPTION);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_SLEEPING);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_FUTEX);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_PORT);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_CHANNEL);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_WAIT_ONE);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_WAIT_MANY);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_INTERRUPT);
    CASE_TO_STR(ZX_THREAD_STATE_BLOCKED_PAGER);
    default:
      return nullptr;
  }
#undef CASE_TO_STR
}

const std::string ThreadOsStateNameAsString(uint32_t state) {
  const char* name = ThreadOsStateName(state);
  if (name) {
    return std::string(name);
  }
  return fxl::StringPrintf("UNKNOWN(%u)", state);
}

zx_status_t WithThreadSuspended(const zx::thread& thread, zx::duration thread_suspend_timeout,
                                const WithThreadSuspendedFunction& function) {
  zx::suspend_token suspend_token;
  auto status = thread.suspend(&suspend_token);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "unable to suspend thread " << GetKoid(thread) << ": "
                   << ZxErrorString(status);
    return status;
  }

  zx_signals_t pending;
  status = thread.wait_one(ZX_THREAD_SUSPENDED | ZX_THREAD_TERMINATED,
                           zx::deadline_after(thread_suspend_timeout), &pending);
  if (status != ZX_OK) {
    FXL_LOG(ERROR) << "error waiting for thread " << GetKoid(thread)
                   << " to suspend: " << ZxErrorString(status);
    return status;
  }
  if (pending & ZX_THREAD_TERMINATED) {
    FXL_LOG(WARNING) << "thread " << GetKoid(thread) << " terminated";
    return ZX_ERR_NOT_FOUND;
  }

  return function(thread);
}

zx_status_t WithAllThreadsSuspended(const std::vector<zx::thread>& threads,
                                    zx::duration thread_suspend_timeout,
                                    const WithThreadSuspendedFunction& function) {
  std::vector<zx::suspend_token> suspend_tokens;
  for (const auto& thread : threads) {
    zx::suspend_token suspend_token;
    auto status = thread.suspend(&suspend_token);
    if (status != ZX_OK) {
      FXL_LOG(WARNING) << "unable to suspend thread " << GetKoid(thread) << ": "
                       << ZxErrorString(status);
      suspend_tokens.emplace_back(zx::suspend_token{});
    } else {
      suspend_tokens.emplace_back(std::move(suspend_token));
    }
  }

  for (size_t i = 0; i < threads.size(); ++i) {
    if (!suspend_tokens[i].is_valid())
      continue;
    zx_signals_t pending;
    const zx::thread& thread{threads[i]};
    auto status = thread.wait_one(ZX_THREAD_SUSPENDED | ZX_THREAD_TERMINATED,
                                  zx::deadline_after(thread_suspend_timeout), &pending);
    if (status != ZX_OK) {
      FXL_LOG(ERROR) << "error waiting for thread " << GetKoid(thread)
                     << " to suspend: " << ZxErrorString(status);
      return status;
    }
    if (pending & ZX_THREAD_TERMINATED) {
      FXL_LOG(WARNING) << "thread " << GetKoid(thread) << " terminated";
      suspend_tokens[i].reset();
      continue;
    }
  }

  for (size_t i = 0; i < threads.size(); ++i) {
    if (suspend_tokens[i].is_valid()) {
      const zx::thread& thread{threads[i]};
      auto status = function(thread);
      if (status != ZX_OK)
        return status;
    }
  }

  return ZX_OK;
}

}  // namespace debugger_utils
