// Copyright 2018 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/fuchsia/koid_utilities.h"

#include <fuchsia/sysinfo/c/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/zx/channel.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>

#include <vector>

#include "base/files/file_path.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "util/file/file_io.h"

namespace crashpad {

namespace {

// Casts |handle| into a container of type T, returning a null handle if the
// actual handle type does not match that of T.
template <typename T>
T CastHandle(zx::handle handle) {
  zx_info_handle_basic_t actual = {};
  zx_status_t status = handle.get_info(
      ZX_INFO_HANDLE_BASIC, &actual, sizeof(actual), nullptr, nullptr);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_get_info";
    return T();
  }
  if (actual.type != T::TYPE) {
    LOG(ERROR) << "Wrong type: " << actual.type << ", expected " << T::TYPE;
    return T();
  }
  return T(std::move(handle));
}

// Returns null handle if |koid| is not found or an error occurs. If |was_found|
// is non-null then it will be set, to distinguish not-found from other errors.
template <typename T, typename U>
T GetChildHandleByKoid(const U& parent, zx_koid_t child_koid, bool* was_found) {
  zx::handle handle;
  zx_status_t status =
      parent.get_child(child_koid, ZX_RIGHT_SAME_RIGHTS, &handle);
  if (was_found)
    *was_found = (status != ZX_ERR_NOT_FOUND);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_get_child";
    return T();
  }

  return CastHandle<T>(std::move(handle));
}

}  // namespace

std::vector<zx_koid_t> GetChildKoids(const zx::object_base& parent_object,
                                     zx_object_info_topic_t child_kind) {
  size_t actual = 0;
  size_t available = 0;
  std::vector<zx_koid_t> result(100);
  zx::unowned_handle parent(parent_object.get());

  // This is inherently racy. Better if the process is suspended, but there's
  // still no guarantee that a thread isn't externally created. As a result,
  // must be in a retry loop.
  for (;;) {
    zx_status_t status = parent->get_info(child_kind,
                                          result.data(),
                                          result.size() * sizeof(zx_koid_t),
                                          &actual,
                                          &available);
    // If the buffer is too small (even zero), the result is still ZX_OK, not
    // ZX_ERR_BUFFER_TOO_SMALL.
    if (status != ZX_OK) {
      ZX_LOG(ERROR, status) << "zx_object_get_info";
      break;
    }

    if (actual == available) {
      break;
    }

    // Resize to the expected number next time, with a bit of slop to handle the
    // race between here and the next request.
    result.resize(available + 10);
  }

  result.resize(actual);
  return result;
}

std::vector<zx::thread> GetThreadHandles(const zx::process& parent) {
  auto koids = GetChildKoids(parent, ZX_INFO_PROCESS_THREADS);
  return GetHandlesForThreadKoids(parent, koids);
}

std::vector<zx::thread> GetHandlesForThreadKoids(
    const zx::process& parent,
    const std::vector<zx_koid_t>& koids) {
  std::vector<zx::thread> result;
  result.reserve(koids.size());
  for (zx_koid_t koid : koids) {
    result.emplace_back(GetThreadHandleByKoid(parent, koid));
  }
  return result;
}

zx::thread GetThreadHandleByKoid(const zx::process& parent,
                                 zx_koid_t child_koid) {
  return GetChildHandleByKoid<zx::thread>(parent, child_koid, nullptr);
}

zx_koid_t GetKoidForHandle(const zx::object_base& object) {
  zx_info_handle_basic_t info;
  zx_status_t status = zx_object_get_info(object.get(),
                                          ZX_INFO_HANDLE_BASIC,
                                          &info,
                                          sizeof(info),
                                          nullptr,
                                          nullptr);
  if (status != ZX_OK) {
    ZX_LOG(ERROR, status) << "zx_object_get_info";
    return ZX_KOID_INVALID;
  }
  return info.koid;
}

}  // namespace crashpad
