// Copyright 2019 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 "zx.h"

#include <zircon/process.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include <iostream>
#include <iterator>
#include <memory>
#include <string>

#include "src/lib/fidl_codec/printer.h"
#include "third_party/quickjs/quickjs-libc.h"
#include "third_party/quickjs/quickjs.h"

// This file contains bindings that allow JavaScript code to invoke syscalls.

namespace shell::zx {

// Converts a zx_status_t into a JavaScript error and throws it.
JSValue ZxStatusToError(JSContext *ctx, zx_status_t status) {
  if (status == ZX_OK) {
    return JS_UNDEFINED;
  }
  JSValue obj = JS_NewError(ctx);
  JS_DefinePropertyValueStr(ctx, obj, "message", JS_NewString(ctx, zx_status_get_string(status)),
                            JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
  JS_DefinePropertyValueStr(ctx, obj, "status", JS_NewInt32(ctx, status),
                            JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE);
  return JS_Throw(ctx, obj);
}

JSClassID handle_class_id_;

JSClassDef handle_class_ = {
    "Handle",
    .finalizer = nullptr,
};

zx_handle_disposition_t HandleFromJsval(JSValue val) {
  auto opaque = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque(val, handle_class_id_));
  zx_handle_disposition_t handle;
  handle.operation = fidl_codec::kNoHandleDisposition;
  handle.handle = opaque->handle;
  handle.type = opaque->type;
  handle.rights = ZX_RIGHT_NONE;
  handle.result = ZX_OK;
  return handle;
}

JSValue HandleCreate(JSContext *ctx, zx_handle_t handle, zx_obj_type_t type) {
  JSValue obj = JS_NewObjectClass(ctx, handle_class_id_);
  if (JS_IsException(obj)) {
    return obj;
  }
  auto s = reinterpret_cast<JSFuchsiaHandle *>(js_mallocz(ctx, sizeof(JSFuchsiaHandle)));
  if (!s) {
    JS_FreeValue(ctx, obj);
    return JS_EXCEPTION;
  }
  s->handle = handle;
  s->type = type;
  JS_SetOpaque(obj, s);
  return obj;
}

JSValue HandleClose(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_ThrowSyntaxError(ctx, "Wrong number of arguments to zx.close(), was %d, expected 1",
                               argc);
  }
  auto h = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, argv[0], handle_class_id_));
  if (!h) {
    return JS_EXCEPTION;
  }
  stop_waiting_for_zx_handle(JS_GetRuntime(ctx), h, -1);
  zx_handle_close(h->handle);
  h->handle = ZX_HANDLE_INVALID;
  return JS_UNDEFINED;
}

JSValue ObjectWaitAsync(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 3) {
    return JS_ThrowSyntaxError(ctx, "Wrong number of arguments to zx.close(), was %d, expected 3",
                               argc);
  }

  auto h = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, argv[0], handle_class_id_));
  if (!h) {
    return JS_EXCEPTION;
  }

  uint32_t signals;
  if (JS_ToUint32(ctx, &signals, argv[1])) {
    return JS_EXCEPTION;
  }

  if (!JS_IsFunction(ctx, argv[2])) {
    return JS_ThrowTypeError(ctx, "Expected a function");
  }

  if (zx_object_get_info(h->handle, ZX_INFO_HANDLE_VALID, NULL, 0, NULL, NULL) ==
      ZX_ERR_BAD_HANDLE) {
    return JS_ThrowTypeError(ctx, "Invalid handle");
  }

  wait_for_zx_handle(ctx, h, signals, &argv[2]);

  return JS_UNDEFINED;
}

JSValue ChannelCreate(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  zx_handle_t out0, out1;
  zx_status_t status = zx_channel_create(0, &out0, &out1);
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }

  JSValue handles = JS_NewArray(ctx);
  JS_SetPropertyUint32(ctx, handles, 0, HandleCreate(ctx, out0, ZX_OBJ_TYPE_CHANNEL));
  JS_SetPropertyUint32(ctx, handles, 1, HandleCreate(ctx, out1, ZX_OBJ_TYPE_CHANNEL));
  return handles;
}

// This gets passed a Handle object.
// TODO(jeremymanson): Support flags
JSValue ChannelRead(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_ThrowSyntaxError(
        ctx, "Wrong number of arguments to zx.channelRead(), was %d, expected 1", argc);
  }
  auto h = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, argv[0], handle_class_id_));
  if (!h) {
    return JS_EXCEPTION;
  }

  uint32_t num_bytes;
  uint8_t bytes[ZX_CHANNEL_MAX_MSG_BYTES];
  uint32_t num_handles;
  zx_handle_info_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];

  zx_status_t status = zx_channel_read_etc(h->handle, 0, bytes, handles, std::size(bytes),
                                           std::size(handles), &num_bytes, &num_handles);
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }

  JSValue bytes_buffer = JS_NewArrayBufferCopy(ctx, bytes, num_bytes);
  JSValue handles_array = JS_NewArray(ctx);
  for (uint32_t i = 0; i < num_handles; i++) {
    JS_SetPropertyUint32(ctx, handles_array, i,
                         HandleCreate(ctx, handles[i].handle, handles[i].type));
  }

  // TODO(jeremymanson): We can do better than an array here.
  JSValue ret = JS_NewArray(ctx);
  JS_SetPropertyUint32(ctx, ret, 0, bytes_buffer);
  JS_SetPropertyUint32(ctx, ret, 1, handles_array);

  return ret;
}

// Takes a Handle, an array of bytes, and an array of Handles.
// TODO(jeremymanson): Should this be an array of zx.Objects?
JSValue ChannelWrite(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 3) {
    return JS_ThrowSyntaxError(ctx, "Wrong number of arguments to zx.write(), was %d, expected 3",
                               argc);
  }

  auto h = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, argv[0], handle_class_id_));
  if (!h) {
    return JS_EXCEPTION;
  }

  size_t num_bytes;
  uint8_t *bytes = JS_GetArrayBuffer(ctx, &num_bytes, argv[1]);
  if (!bytes) {
    return JS_ThrowTypeError(ctx, "Expected an ArrayBuffer");
  }
  if (num_bytes > ZX_CHANNEL_MAX_MSG_BYTES) {
    return JS_ThrowRangeError(ctx, "Message length exceeds %d bytes", ZX_CHANNEL_MAX_MSG_BYTES);
  }

  zx_handle_t handles[ZX_CHANNEL_MAX_MSG_HANDLES];
  uint32_t num_handles;
  if (!JS_IsArray(ctx, argv[2])) {
    return JS_ThrowTypeError(ctx, "Expected an Array");
  }
  JSValue num_handles_value = JS_GetPropertyStr(ctx, argv[2], "length");
  if (JS_IsException(num_handles_value)) {
    return num_handles_value;
  }
  if (JS_ToUint32(ctx, &num_handles, num_handles_value)) {
    return JS_EXCEPTION;
  }
  if (num_handles > ZX_CHANNEL_MAX_MSG_HANDLES) {
    return JS_ThrowRangeError(ctx, "Message handle count exceeds %d", ZX_CHANNEL_MAX_MSG_HANDLES);
  }
  for (uint32_t i = 0; i < num_handles; i++) {
    JSValue item = JS_GetPropertyUint32(ctx, argv[2], i);
    auto ih = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, item, handle_class_id_));
    if (!ih) {
      return JS_ThrowTypeError(ctx, "Expected a handle at index %d into handle array", i);
    }
    handles[i] = ih->handle;
    ih->handle = ZX_HANDLE_INVALID;
  }

  zx_status_t status = zx_channel_write(h->handle, 0, bytes, num_bytes, handles, num_handles);

  return ZxStatusToError(ctx, status);
}

JSValue Duplicate(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv) {
  if (argc != 2) {
    return JS_ThrowSyntaxError(ctx, "Wrong number of arguments to zx.write(), was %d, expected 2",
                               argc);
  }
  auto h = reinterpret_cast<JSFuchsiaHandle *>(JS_GetOpaque2(ctx, argv[0], handle_class_id_));
  if (!h) {
    return JS_EXCEPTION;
  }
  uint32_t right_mask;
  if (JS_ToUint32(ctx, &right_mask, argv[1])) {
    return JS_EXCEPTION;
  }
  zx_handle_t out;
  zx_status_t status = zx_handle_duplicate(h->handle, right_mask, &out);
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }
  return HandleCreate(ctx, out, h->type);
}

// Converts a number to a Handle object, where number is a zx_handle_t that the code
// got from somewhere.
// argv[0] is the Number.
static JSValue HandleFromInt(JSContext *ctx, JSValueConst /*this_val*/, int argc,
                             JSValueConst *argv) {
  if (argc != 1) {
    return JS_EXCEPTION;
  }

  zx_handle_t handle;
  if (JS_ToInt32(ctx, reinterpret_cast<int32_t *>(&handle), argv[0])) {
    return JS_EXCEPTION;
  }

  zx_info_handle_basic_t basic;
  if (zx_object_get_info(handle, ZX_INFO_HANDLE_BASIC, &basic, sizeof(basic), nullptr, nullptr) !=
      ZX_OK) {
    return JS_ThrowTypeError(ctx, "Invalid handle");
  }
  return HandleCreate(ctx, handle, basic.type);
}

// Calls zx_object_get_child.
// argv[0] is the handle
// argv[1] is the koid for which you want the handle.
// argv[2] is the rights you have on the child handle.
// Returns the handle of the child.
JSValue GetChild(JSContext *ctx, JSValueConst /*this_val*/, int argc, JSValueConst *argv) {
  if (argc != 3) {
    return JS_ThrowSyntaxError(ctx, "Bad arguments to zx.getChild()");
  }
  static_assert(sizeof(zx_rights_t) == sizeof(uint32_t));
  uint64_t koid;
  zx_rights_t rights;
  zx_handle_disposition_t handle_disposition = HandleFromJsval(argv[0]);
  JS_ToInt64(ctx, reinterpret_cast<int64_t *>(&koid), argv[1]);
  JS_ToInt32(ctx, reinterpret_cast<int32_t *>(&rights), argv[2]);
  zx_handle_t out;
  zx_status_t status = zx_object_get_child(handle_disposition.handle, koid, rights, &out);
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }
  zx_info_handle_basic_t basic;
  if (zx_object_get_info(out, ZX_INFO_HANDLE_BASIC, &basic, sizeof(basic), nullptr, nullptr) !=
      ZX_OK) {
    return JS_ThrowTypeError(ctx, "Invalid handle");
  }
  return HandleCreate(ctx, out, basic.type);
}

// Provides a generic interface for dealing with the output of zx_object_get_info, that
// can be specialized for the kind of info we're getting.
class GetInfoController {
 public:
  GetInfoController(JSContext *ctx, uint32_t topic) : ctx_(ctx), topic_(topic) {}
  virtual ~GetInfoController() = default;

  // Creates a buffer for the output of zx_object_get_info.  |size| is a hint, and may be
  // ignored if you know better.  However, if it isn't enough room, we'll loop until it is.
  virtual void *SetBuffer(size_t size) = 0;

  // Gets the current buffer size.
  virtual size_t BufferSize() = 0;

  // Gets a reference to the buffer.
  virtual void *GetBuffer() = 0;

  // Converts the contents of the buffer into a JSValue (usually with the same fields as the struct)
  virtual JSValue GetValues(size_t actual) = 0;

  // Gets the controller for the given |topic|, where topic is the same as the topic of the
  // zx_object_get_info.
  static GetInfoController *GetCorrectController(JSContext *ctx, uint32_t topic);

 protected:
  JSContext *ctx_;
  uint32_t topic_;
};

// GetInfoController for zx_koid_t[]
class KoidInfoController : public GetInfoController {
 public:
  KoidInfoController(JSContext *ctx, uint32_t topic) : GetInfoController(ctx, topic) {}
  void *SetBuffer(size_t size) override {
    auto *arr = new zx_koid_t[size];
    buffer_.reset(arr);
    size_ = size;
    return reinterpret_cast<void *>(arr);
  }
  size_t BufferSize() override { return size_; }
  void *GetBuffer() override { return buffer_.get(); }
  JSValue GetValues(size_t actual) override {
    JSValue arr = JS_NewArray(ctx_);
    for (size_t i = 0; i < actual; i++) {
      JS_SetPropertyUint32(ctx_, arr, i, JS_NewInt64(ctx_, buffer_.get()[i]));
    }
    return arr;
  }

 private:
  std::unique_ptr<zx_koid_t[]> buffer_;
  size_t size_;
};

// GetInfoController for zx_info_handle_basic_t.
class BasicInfoController : public GetInfoController {
 public:
  BasicInfoController(JSContext *ctx, uint32_t topic) : GetInfoController(ctx, topic) {}
  size_t BufferSize() override { return sizeof(basic_info_); }
  void *GetBuffer() override { return &basic_info_; }
  void *SetBuffer(size_t /*size*/) override { return GetBuffer(); }
  JSValue GetValues(size_t /*actual*/) override {
    JSValue object = JS_NewObject(ctx_);

    if (JS_SetPropertyStr(ctx_, object, "koid", JS_NewInt32(ctx_, basic_info_.koid)) != 1) {
      return JS_ThrowInternalError(ctx_, "Unable to set koid");
    }
    if (JS_SetPropertyStr(ctx_, object, "rights", JS_NewInt32(ctx_, basic_info_.rights)) != 1) {
      return JS_ThrowInternalError(ctx_, "Unable to set rights");
    }
    if (JS_SetPropertyStr(ctx_, object, "type", JS_NewInt32(ctx_, basic_info_.type)) != 1) {
      return JS_ThrowInternalError(ctx_, "Unable to set type");
    }
    if (JS_SetPropertyStr(ctx_, object, "related_koid",
                          JS_NewInt32(ctx_, basic_info_.related_koid)) != 1) {
      return JS_ThrowInternalError(ctx_, "Unable to set related_koid");
    }
    return object;
  }

 private:
  zx_info_handle_basic_t basic_info_;
};

GetInfoController *GetInfoController::GetCorrectController(JSContext *ctx, uint32_t topic) {
  switch (topic) {
    case ZX_INFO_JOB_CHILDREN:
    case ZX_INFO_JOB_PROCESSES:
    case ZX_INFO_PROCESS_THREADS:
      return new KoidInfoController(ctx, topic);
    case ZX_INFO_HANDLE_VALID:
      return nullptr;
    case ZX_INFO_HANDLE_BASIC:
      return new BasicInfoController(ctx, topic);
    case ZX_INFO_PROCESS_V1:
    case ZX_INFO_PROCESS_V2:
    case ZX_INFO_VMAR:
    case ZX_INFO_THREAD:
    case ZX_INFO_THREAD_EXCEPTION_REPORT:
    case ZX_INFO_TASK_STATS:
    case ZX_INFO_PROCESS_MAPS:
    case ZX_INFO_PROCESS_VMOS:
    case ZX_INFO_THREAD_STATS:
    case ZX_INFO_CPU_STATS:
    case ZX_INFO_KMEM_STATS:
    case ZX_INFO_RESOURCE:
    case ZX_INFO_HANDLE_COUNT:
    case ZX_INFO_BTI:
    case ZX_INFO_PROCESS_HANDLE_STATS:
    case ZX_INFO_SOCKET:
    case ZX_INFO_VMO:
    default:
      return nullptr;
  }
}

// Calls zx_object_get_info, and returns a JSValue that looks like the struct returned
// by that call.
// argv[0] is a handle, argv[1] is the topic
JSValue ObjectGetInfo(JSContext *ctx, JSValueConst /*this_val*/, int argc, JSValueConst *argv) {
  if (argc != 2) {
    return JS_ThrowSyntaxError(ctx, "Bad arguments to zx.objectGetInfo");
  }
  zx_handle_disposition_t handle_disposition = HandleFromJsval(argv[0]);
  uint32_t topic;
  if (JS_ToUint32(ctx, &topic, argv[1])) {
    return JS_ThrowSyntaxError(ctx, "Bad topic for zx.objectGetInfo");
  }
  GetInfoController *c = GetInfoController::GetCorrectController(ctx, topic);
  if (c == nullptr) {
    std::string msg = "zx.objectGetInfo topic " + std::to_string(topic) + " not implemented";
    return JS_ThrowSyntaxError(ctx, "%s", msg.c_str());
  }
  std::unique_ptr<GetInfoController> controller;
  controller.reset(c);
  std::unique_ptr<void *> buffer;
  size_t actual;
  size_t avail;
  constexpr size_t kMaxAttempts = 5;
  size_t attempt = 0;
  // 16 seems like a nice round number.
  size_t buffer_size = 16;
  do {
    attempt++;
    void *buffer = controller->SetBuffer(buffer_size);
    zx_status_t status = zx_object_get_info(handle_disposition.handle, topic, buffer,
                                            controller->BufferSize(), &actual, &avail);
    if (status != ZX_OK) {
      return ZxStatusToError(ctx, status);
    }
    buffer_size *= 2;
  } while (actual < avail && attempt < kMaxAttempts);
  return controller->GetValues(actual);
}

// argv[0] is a handle
// argv[1] is a legal property for zx_object_get_property.
JSValue ObjectGetProperty(JSContext *ctx, JSValueConst /*this_val*/, int argc, JSValueConst *argv) {
  if (argc != 2) {
    return JS_ThrowSyntaxError(ctx, "Bad arguments to zx.objectGetProperty");
  }
  zx_handle_disposition_t handle_disposition = HandleFromJsval(argv[0]);
  uint32_t property;
  if (JS_ToUint32(ctx, &property, argv[1])) {
    return JS_ThrowSyntaxError(ctx, "Bad property for zx.objectGetProperty");
  }
  if (property != ZX_PROP_NAME) {
    return JS_ThrowInternalError(ctx, "Operation %d not supported on zx.objectGetProperty",
                                 property);
  }
  char name[ZX_MAX_NAME_LEN];
  zx_status_t status =
      zx_object_get_property(handle_disposition.handle, property, name, sizeof(name));
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }
  return JS_NewString(ctx, name);
}

JSValue ProcessSelf(JSContext *ctx, JSValueConst /*this_val*/, int /*argc*/,
                    JSValueConst * /*argv*/) {
  zx_handle_t self = zx_process_self();
  return HandleCreate(ctx, self, ZX_OBJ_TYPE_PROCESS);
}

JSValue JobDefault(JSContext *ctx, JSValueConst /*this_val*/, int /*argc*/,
                   JSValueConst * /*argv*/) {
  zx_handle_t d = zx_job_default();
  return HandleCreate(ctx, d, ZX_OBJ_TYPE_JOB);
}

// Calls zx_task_kill
// argv[0] is a handle to the task to kill
JSValue Kill(JSContext *ctx, JSValueConst /*this_val*/, int argc, JSValueConst *argv) {
  if (argc != 1) {
    return JS_ThrowSyntaxError(ctx, "Bad arguments to zx.kill");
  }
  zx_handle_disposition_t handle_disposition = HandleFromJsval(argv[0]);

  zx_status_t status = zx_task_kill(handle_disposition.handle);
  if (status != ZX_OK) {
    return ZxStatusToError(ctx, status);
  }
  return JS_NewInt32(ctx, 0);
}

#define FLAG(x) JS_PROP_INT32_DEF(#x, x, JS_PROP_CONFIGURABLE)
#define FLAG_64(x) JS_PROP_INT64_DEF(#x, x, JS_PROP_CONFIGURABLE)

const JSCFunctionListEntry funcs_[] = {
    /* Fuchsia handle operations */
    JS_CFUNC_DEF("channelCreate", 0, ChannelCreate), JS_CFUNC_DEF("channelRead", 0, ChannelRead),
    JS_CFUNC_DEF("channelWrite", 0, ChannelWrite), JS_CFUNC_DEF("handleClose", 0, HandleClose),
    JS_CFUNC_DEF("objectWaitAsync", 0, ObjectWaitAsync), JS_CFUNC_DEF("duplicate", 0, Duplicate),
    JS_CFUNC_DEF("getChild", 0, GetChild), JS_CFUNC_DEF("handleFromInt", 0, HandleFromInt),
    JS_CFUNC_DEF("getObjectInfo", 2, ObjectGetInfo),
    JS_CFUNC_DEF("getObjectProperty", 2, ObjectGetProperty),
    JS_CFUNC_DEF("jobDefault", 2, JobDefault), JS_CFUNC_DEF("processSelf", 2, ProcessSelf),
    JS_CFUNC_DEF("kill", 1, Kill),
    /* Handle signal constants */
    FLAG(ZX_CHANNEL_READABLE), FLAG(ZX_CHANNEL_WRITABLE), FLAG(ZX_CHANNEL_PEER_CLOSED),
    /* zx_object_get_info flags */
    FLAG(ZX_INFO_NONE), FLAG(ZX_INFO_HANDLE_VALID), FLAG(ZX_INFO_HANDLE_BASIC),
    FLAG(ZX_INFO_PROCESS_V1), FLAG(ZX_INFO_PROCESS_V2), FLAG(ZX_INFO_PROCESS_THREADS),
    FLAG(ZX_INFO_VMAR), FLAG(ZX_INFO_JOB_CHILDREN), FLAG(ZX_INFO_JOB_PROCESSES),
    FLAG(ZX_INFO_THREAD), FLAG(ZX_INFO_THREAD_EXCEPTION_REPORT), FLAG(ZX_INFO_TASK_STATS),
    FLAG(ZX_INFO_PROCESS_MAPS), FLAG(ZX_INFO_PROCESS_VMOS), FLAG(ZX_INFO_THREAD_STATS),
    FLAG(ZX_INFO_CPU_STATS), FLAG(ZX_INFO_KMEM_STATS), FLAG(ZX_INFO_RESOURCE),
    FLAG(ZX_INFO_HANDLE_COUNT), FLAG(ZX_INFO_BTI), FLAG(ZX_INFO_PROCESS_HANDLE_STATS),
    FLAG(ZX_INFO_SOCKET), FLAG(ZX_INFO_VMO),
    /* zx_object_get_property flags */
    FLAG(ZX_PROP_NAME), FLAG_64(ZX_RIGHT_SAME_RIGHTS)};

namespace {

int ZxRunOnInit(JSContext *ctx, JSModuleDef *m) {
  JS_NewClassID(&handle_class_id_);
  JS_NewClass(JS_GetRuntime(ctx), handle_class_id_, &handle_class_);
  return JS_SetModuleExportList(ctx, m, funcs_, std::size(funcs_));
}

}  // namespace

JSModuleDef *ZxModuleInit(JSContext *ctx, const char *module_name) {
  JSModuleDef *m = JS_NewCModule(ctx, module_name, ZxRunOnInit);
  if (!m) {
    return nullptr;
  }
  JS_AddModuleExportList(ctx, m, funcs_, std::size(funcs_));
  return m;
}

}  // namespace shell::zx
