// 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>();
}

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::Value> Utf8ArrayToStr(gin::Arguments* args) {
  gin::ArrayBufferView data;
  if (!args->GetNext(&data)) {
    args->ThrowError();
    return v8::Local<v8::Value>();
  }

  // Get the UTF-8 out into a string, and then rely on ConvertToV8 to convert
  // that to a UCS-2 string.
  return gin::StringToV8(
      args->isolate(), base::StringPiece(static_cast<const char*>(data.bytes()),
                                         data.num_bytes()));
}

}  // 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());

#define SET_CONSTANT(k)                             \
  global->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.
  global->Set(
      gin::StringToSymbol(isolate, "$ZxObjectWaitOne"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(ZxObjectWaitOne))
          ->GetFunction());
  SET_CONSTANT(ZX_HANDLE_INVALID);
  SET_CONSTANT(ZX_TIME_INFINITE);

  // Channel APIs.
  global->Set(
      gin::StringToSymbol(isolate, "$ZxChannelWrite"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&ZxChannelWrite))
          ->GetFunction());
  global->Set(
      gin::StringToSymbol(isolate, "$ZxChannelRead"),
      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);

  // Utilities to make string handling easier to convert to/from UCS-2 (JS) <->
  // UTF-8 (FIDL).
  global->Set(
      gin::StringToSymbol(isolate, "$FidlJsStrToUtf8Array"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&StrToUtf8Array))
          ->GetFunction());
  global->Set(
      gin::StringToSymbol(isolate, "$FidlJsUtf8ArrayToStr"),
      gin::CreateFunctionTemplate(isolate, base::BindRepeating(&Utf8ArrayToStr))
          ->GetFunction());

#undef SET_CONSTANT
}

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

}  // namespace fidljs
