// Copyright 2017 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 <zircon/syscalls.h>

#include <task-utils/get.h>
#include <task-utils/walker.h>

typedef struct {
  zx_koid_t desired_koid;
  zx_handle_t found_handle;
  zx_obj_type_t found_type;
} get_task_ctx_t;

static zx_status_t common_callback(zx_obj_type_t type, get_task_ctx_t* ctx, zx_handle_t handle,
                                   zx_koid_t koid) {
  if (koid == ctx->desired_koid) {
    zx_handle_t dup;
    zx_status_t s = zx_handle_duplicate(handle, ZX_RIGHT_SAME_RIGHTS, &dup);
    if (s != ZX_OK) {
      return s;
    }
    ctx->found_handle = dup;
    ctx->found_type = type;
    return ZX_ERR_STOP;
  }
  return ZX_OK;
}

static zx_status_t job_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
                                zx_koid_t parent_koid) {
  return common_callback(ZX_OBJ_TYPE_JOB, ctx, handle, koid);
}

static zx_status_t process_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
                                    zx_koid_t parent_koid) {
  return common_callback(ZX_OBJ_TYPE_PROCESS, ctx, handle, koid);
}

static zx_status_t thread_callback(void* ctx, int depth, zx_handle_t handle, zx_koid_t koid,
                                   zx_koid_t parent_koid) {
  return common_callback(ZX_OBJ_TYPE_THREAD, ctx, handle, koid);
}

zx_status_t get_task_by_koid(zx_koid_t koid, zx_obj_type_t* type, zx_handle_t* out) {
  if (type == NULL || out == NULL) {
    return ZX_ERR_INVALID_ARGS;
  }
  get_task_ctx_t ctx = {
      .desired_koid = koid,
      .found_handle = ZX_HANDLE_INVALID,
      .found_type = ZX_OBJ_TYPE_NONE,
  };
  zx_status_t s = walk_root_job_tree(job_callback, process_callback, thread_callback, &ctx);
  if (s == ZX_ERR_STOP) {
    *type = ctx.found_type;
    *out = ctx.found_handle;
    return ZX_OK;
  }
  if (s == ZX_OK) {
    // The callback would have returned ZX_ERR_STOP if it found anything.
    return ZX_ERR_NOT_FOUND;
  }
  return s;
}
