// Copyright 2018 The Chromium 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 "tools/fuchsia/fidlgen_js/runtime/zircon.h"

#include <lib/async/default.h>
#include <lib/async/wait.h>
#include <lib/zx/channel.h>
#include <zircon/errors.h>
#include <zircon/syscalls.h>
#include <zircon/types.h>

#include "base/bind.h"
#include "base/threading/thread_checker.h"
#include "gin/arguments.h"
#include "gin/array_buffer.h"
#include "gin/converter.h"
#include "gin/data_object_builder.h"
#include "gin/function_template.h"
#include "gin/public/gin_embedders.h"

namespace {

fidljs::WaitSet& GetWaitsForIsolate(v8::Isolate* isolate) {
  return *static_cast<fidljs::WaitSet*>(
      isolate->GetData(gin::kEmbedderFuchsia));
}

}  // namespace

namespace fidljs {

class WaitPromiseImpl : public async_wait_t {
 public:
  WaitPromiseImpl(v8::Isolate* isolate,
                  v8::Local<v8::Context> context,
                  v8::Local<v8::Promise::Resolver> resolver,
                  zx_handle_t handle,
                  zx_signals_t signals)
      : async_wait_t({ASYNC_STATE_INIT, &WaitPromiseImpl::StaticOnSignaled,
                      handle, signals}),
        isolate_(isolate),
        wait_state_(WaitState::kCreated),
        failed_start_status_(ZX_OK) {
    context_.Reset(isolate_, context);
    resolver_.Reset(isolate_, resolver);
  }

  ~WaitPromiseImpl() {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    switch (wait_state_) {
      case WaitState::kCreated:
        // The wait never started, so reject the promise (but don't attempt to
        // cancel the wait).
        DCHECK_NE(failed_start_status_, ZX_OK);
        RejectPromise(failed_start_status_, 0);
        break;

      case WaitState::kStarted:
        // The wait was started, but has not yet completed. Cancel the wait and
        // reject the promise. The object is being destructed here because it's
        // been removed from the set of waits attached to the isolate, so
        // we need not remove it.
        CHECK_EQ(async_cancel_wait(async_get_default_dispatcher(), this),
                 ZX_OK);
        RejectPromise(ZX_ERR_CANCELED, 0);
        break;

      case WaitState::kCompleted:
        // The callback has already been called and so the promise has been
        // resolved or rejected, and the wait has been removed from the
        // dispatcher, so there's nothing to do.
        break;
    }
  }

  bool BeginWait() {
    DCHECK_EQ(wait_state_, WaitState::kCreated);
    zx_status_t status = async_begin_wait(async_get_default_dispatcher(), this);
    if (status == ZX_OK) {
      wait_state_ = WaitState::kStarted;
    } else {
      failed_start_status_ = status;
    }
    return status == ZX_OK;
  }

 private:
  static void StaticOnSignaled(async_dispatcher_t* dispatcher,
                               async_wait_t* wait,
                               zx_status_t status,
                               const zx_packet_signal_t* signal) {
    auto* self = static_cast<WaitPromiseImpl*>(wait);
    self->OnSignaled(status, signal);
  }

  void OnSignaled(zx_status_t status, const zx_packet_signal_t* signal) {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DCHECK_EQ(wait_state_, WaitState::kStarted);
    DCHECK_NE(status, ZX_ERR_CANCELED)
        << "wait should have been canceled before shutdown";

    wait_state_ = WaitState::kCompleted;

    if (status == ZX_OK &&
        (signal->observed & signal->trigger) == signal->trigger) {
      ResolvePromise(signal->observed);
    } else {
      RejectPromise(status, signal->observed);
    }

    GetWaitsForIsolate(isolate_).erase(this);
    // |this| has been deleted.
  }

  void ResolvePromise(zx_signals_t observed) {
    v8::Local<v8::Promise::Resolver> resolver(resolver_.Get(isolate_));
    v8::Local<v8::Context> context(context_.Get(isolate_));
    v8::Local<v8::Object> value = gin::DataObjectBuilder(isolate_)
                                      .Set("status", ZX_OK)
                                      .Set("observed", observed)
                                      .Build();
    resolver->Resolve(context, value).ToChecked();
  }

  void RejectPromise(zx_status_t status, zx_signals_t observed) {
    v8::Local<v8::Promise::Resolver> resolver(resolver_.Get(isolate_));
    v8::Local<v8::Context> context(context_.Get(isolate_));
    v8::Local<v8::Object> value = gin::DataObjectBuilder(isolate_)
                                      .Set("status", status)
                                      .Set("observed", observed)
                                      .Build();
    resolver->Reject(context, value).ToChecked();
  }

  v8::Isolate* isolate_;
  v8::Global<v8::Context> context_;
  v8::Global<v8::Promise::Resolver> resolver_;
  enum class WaitState {
    kCreated,
    kStarted,
    kCompleted,
  } wait_state_;
  zx_status_t failed_start_status_;

  THREAD_CHECKER(thread_checker_);

  DISALLOW_COPY_AND_ASSIGN(WaitPromiseImpl);
};

}  // namespace fidljs

namespace {

v8::Local<v8::Promise> ZxObjectWaitOne(gin::Arguments* args) {
  zx_handle_t handle;
  if (!args->GetNext(&handle)) {
    args->ThrowError();
    return v8::Local<v8::Promise>();
  }

  zx_signals_t signals;
  if (!args->GetNext(&signals)) {
    args->ThrowError();
    return v8::Local<v8::Promise>();
  }

  v8::MaybeLocal<v8::Promise::Resolver> maybe_resolver =
      v8::Promise::Resolver::New(args->GetHolderCreationContext());
  v8::Local<v8::Promise::Resolver> resolver;
  if (maybe_resolver.ToLocal(&resolver)) {
    auto wait = std::make_unique<fidljs::WaitPromiseImpl>(
        args->isolate(), args->GetHolderCreationContext(), resolver, handle,
        signals);
    if (wait->BeginWait()) {
      // The wait will always be notified asynchronously, so it's OK to delay
      // the add until after it has completed successfully. Move |wait| into the
      // set of active waits.
      GetWaitsForIsolate(args->isolate()).insert(std::move(wait));
    }

    // If BeginWait() fails, then |wait| will be deleted here, causing the
    // returned promise to be rejected.
    return resolver->GetPromise();
  }

  return v8::Local<v8::Promise>();
}

v8::Local<v8::Object> ZxChannelCreate(v8::Isolate* isolate) {
  zx::channel c1, c2;
  zx_status_t status = zx::channel::create(0, &c1, &c2);
  return gin::DataObjectBuilder(isolate)
      .Set("status", status)
      .Set("first", c1.release())
      .Set("second", c2.release())
      .Build();
}

zx_status_t ZxChannelWrite(gin::Arguments* args) {
  zx_handle_t handle;
  if (!args->GetNext(&handle)) {
    args->ThrowError();
    return ZX_ERR_INVALID_ARGS;
  }

  gin::ArrayBufferView data;
  if (!args->GetNext(&data)) {
    args->ThrowError();
    return ZX_ERR_INVALID_ARGS;
  }

  std::vector<zx_handle_t> handles;
  if (!args->GetNext(&handles)) {
    args->ThrowError();
    return ZX_ERR_INVALID_ARGS;
  }

  zx_status_t status =
      zx_channel_write(handle, 0, data.bytes(), data.num_bytes(),
                       handles.data(), handles.size());
  return status;
}

v8::Local<v8::Object> ZxChannelRead(gin::Arguments* args) {
  zx_handle_t handle;
  if (!args->GetNext(&handle)) {
    args->ThrowError();
    return gin::DataObjectBuilder(args->isolate())
        .Set("status", ZX_ERR_INVALID_ARGS)
        .Build();
  }
  zx::unowned_channel ch(handle);

  uint32_t data_size;
  uint32_t num_handles;
  zx_status_t status =
      ch->read(0, nullptr, 0, &data_size, nullptr, 0, &num_handles);
  DCHECK_EQ(status, ZX_ERR_BUFFER_TOO_SMALL);

  std::vector<zx_handle_t> handles;
  handles.resize(num_handles);

  v8::Local<v8::ArrayBuffer> buf =
      v8::ArrayBuffer::New(args->isolate(), data_size);
  uint32_t actual_bytes, actual_handles;
  status = ch->read(0, buf->GetContents().Data(), data_size, &actual_bytes,
                    handles.data(), handles.size(), &actual_handles);
  DCHECK_EQ(actual_bytes, data_size);
  DCHECK_EQ(actual_handles, num_handles);
  CHECK_EQ(actual_handles, 0u) << "Handle passing untested";

  if (status != ZX_OK) {
    return gin::DataObjectBuilder(args->isolate())
        .Set("status", status)
        .Build();
  }

  return gin::DataObjectBuilder(args->isolate())
      .Set("status", status)
      .Set("data", buf)
      .Set("handles", handles)
      .Build();
}

v8::Local<v8::Value> StrToUtf8Array(gin::Arguments* args) {
  std::string str;
  // This converts the string to utf8 from ucs2, so then just repackage the
  // string as an array and return it.
  if (!args->GetNext(&str)) {
    args->ThrowError();
    return v8::Local<v8::Object>();
  }

  // TODO(crbug.com/883496): Not sure how to make a Uint8Array to return here
  // which would be a bit more efficient.
  std::vector<int> data;
  std::copy(str.begin(), str.end(), std::back_inserter(data));
  return gin::ConvertToV8(args->isolate(), data);
}

v8::Local<v8::Object> GetOrCreateZxObject(v8::Isolate* isolate,
                                          v8::Local<v8::Object> global) {
  v8::Local<v8::Object> zx;
  v8::Local<v8::Value> zx_value = global->Get(gin::StringToV8(isolate, "zx"));
  if (zx_value.IsEmpty() || !zx_value->IsObject()) {
    zx = v8::Object::New(isolate);
    global->Set(gin::StringToSymbol(isolate, "zx"), zx);
  } else {
    zx = v8::Local<v8::Object>::Cast(zx);
  }
  return zx;
}

}  // namespace

namespace fidljs {

ZxBindings::ZxBindings(v8::Isolate* isolate, v8::Local<v8::Object> global)
    : isolate_(isolate), wait_set_(std::make_unique<WaitSet>()) {
  DCHECK_EQ(isolate->GetData(gin::kEmbedderFuchsia), nullptr);
  isolate->SetData(gin::kEmbedderFuchsia, wait_set_.get());

  v8::Local<v8::Object> zx = GetOrCreateZxObject(isolate, global);

#define SET_CONSTANT(k) \
  zx->Set(gin::StringToSymbol(isolate, #k), gin::ConvertToV8(isolate, k))

  // zx_status_t.
  SET_CONSTANT(ZX_OK);
  SET_CONSTANT(ZX_ERR_INTERNAL);
  SET_CONSTANT(ZX_ERR_NOT_SUPPORTED);
  SET_CONSTANT(ZX_ERR_NO_RESOURCES);
  SET_CONSTANT(ZX_ERR_NO_MEMORY);
  SET_CONSTANT(ZX_ERR_INTERNAL_INTR_RETRY);
  SET_CONSTANT(ZX_ERR_INVALID_ARGS);
  SET_CONSTANT(ZX_ERR_BAD_HANDLE);
  SET_CONSTANT(ZX_ERR_WRONG_TYPE);
  SET_CONSTANT(ZX_ERR_BAD_SYSCALL);
  SET_CONSTANT(ZX_ERR_OUT_OF_RANGE);
  SET_CONSTANT(ZX_ERR_BUFFER_TOO_SMALL);
  SET_CONSTANT(ZX_ERR_BAD_STATE);
  SET_CONSTANT(ZX_ERR_TIMED_OUT);
  SET_CONSTANT(ZX_ERR_SHOULD_WAIT);
  SET_CONSTANT(ZX_ERR_CANCELED);
  SET_CONSTANT(ZX_ERR_PEER_CLOSED);
  SET_CONSTANT(ZX_ERR_NOT_FOUND);
  SET_CONSTANT(ZX_ERR_ALREADY_EXISTS);
  SET_CONSTANT(ZX_ERR_ALREADY_BOUND);
  SET_CONSTANT(ZX_ERR_UNAVAILABLE);
  SET_CONSTANT(ZX_ERR_ACCESS_DENIED);
  SET_CONSTANT(ZX_ERR_IO);
  SET_CONSTANT(ZX_ERR_IO_REFUSED);
  SET_CONSTANT(ZX_ERR_IO_DATA_INTEGRITY);
  SET_CONSTANT(ZX_ERR_IO_DATA_LOSS);
  SET_CONSTANT(ZX_ERR_IO_NOT_PRESENT);
  SET_CONSTANT(ZX_ERR_IO_OVERRUN);
  SET_CONSTANT(ZX_ERR_IO_MISSED_DEADLINE);
  SET_CONSTANT(ZX_ERR_IO_INVALID);
  SET_CONSTANT(ZX_ERR_BAD_PATH);
  SET_CONSTANT(ZX_ERR_NOT_DIR);
  SET_CONSTANT(ZX_ERR_NOT_FILE);
  SET_CONSTANT(ZX_ERR_FILE_BIG);
  SET_CONSTANT(ZX_ERR_NO_SPACE);
  SET_CONSTANT(ZX_ERR_NOT_EMPTY);
  SET_CONSTANT(ZX_ERR_STOP);
  SET_CONSTANT(ZX_ERR_NEXT);
  SET_CONSTANT(ZX_ERR_ASYNC);
  SET_CONSTANT(ZX_ERR_PROTOCOL_NOT_SUPPORTED);
  SET_CONSTANT(ZX_ERR_ADDRESS_UNREACHABLE);
  SET_CONSTANT(ZX_ERR_ADDRESS_IN_USE);
  SET_CONSTANT(ZX_ERR_NOT_CONNECTED);
  SET_CONSTANT(ZX_ERR_CONNECTION_REFUSED);
  SET_CONSTANT(ZX_ERR_CONNECTION_RESET);
  SET_CONSTANT(ZX_ERR_CONNECTION_ABORTED);

  // Handle APIs.
  zx->Set(gin::StringToSymbol(isolate, "handleClose"),
          gin::CreateFunctionTemplate(isolate,
                                      base::BindRepeating(&zx_handle_close))
              ->GetFunction());
  SET_CONSTANT(ZX_HANDLE_INVALID);
  zx->Set(
      gin::StringToSymbol(isolate, "objectWaitOne"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(ZxObjectWaitOne))
          ->GetFunction());
  SET_CONSTANT(ZX_HANDLE_INVALID);
  SET_CONSTANT(ZX_TIME_INFINITE);

  // Channel APIs.
  zx->Set(gin::StringToSymbol(isolate, "channelCreate"),
          gin::CreateFunctionTemplate(isolate,
                                      base::BindRepeating(&ZxChannelCreate))
              ->GetFunction());
  zx->Set(
      gin::StringToSymbol(isolate, "channelWrite"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ZxChannelWrite))
          ->GetFunction());
  zx->Set(
      gin::StringToSymbol(isolate, "channelRead"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ZxChannelRead))
          ->GetFunction());
  SET_CONSTANT(ZX_CHANNEL_READABLE);
  SET_CONSTANT(ZX_CHANNEL_WRITABLE);
  SET_CONSTANT(ZX_CHANNEL_PEER_CLOSED);
  SET_CONSTANT(ZX_CHANNEL_READ_MAY_DISCARD);
  SET_CONSTANT(ZX_CHANNEL_MAX_MSG_BYTES);
  SET_CONSTANT(ZX_CHANNEL_MAX_MSG_HANDLES);

  // Utility to make string handling easier to convert from a UCS2 JS string to
  // an array of UTF-8 (which is how strings are represented in FIDL).
  // TODO(crbug.com/883496): This is not really zx, should move to a generic
  // runtime helper file if there are more similar C++ helpers required.
  zx->Set(
      gin::StringToSymbol(isolate, "strToUtf8Array"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&StrToUtf8Array))
          ->GetFunction());

#undef SET_CONSTANT
}

ZxBindings::~ZxBindings() {
  wait_set_->clear();
  isolate_->SetData(gin::kEmbedderFuchsia, nullptr);
}

}  // namespace fidljs
