// Copyright 2014 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 "mojo/bindings/js/core.h"

#include "base/bind.h"
#include "base/logging.h"
#include "gin/arguments.h"
#include "gin/array_buffer.h"
#include "gin/converter.h"
#include "gin/dictionary.h"
#include "gin/function_template.h"
#include "gin/handle.h"
#include "gin/object_template_builder.h"
#include "gin/per_isolate_data.h"
#include "gin/public/wrapper_info.h"
#include "gin/wrappable.h"
#include "mojo/bindings/js/drain_data.h"
#include "mojo/bindings/js/handle.h"

namespace mojo {
namespace js {

namespace {

MojoResult CloseHandle(gin::Handle<HandleWrapper> handle) {
  if (!handle->get().is_valid())
    return MOJO_RESULT_INVALID_ARGUMENT;
  handle->Close();
  return MOJO_RESULT_OK;
}

MojoResult WaitHandle(mojo::Handle handle,
                      MojoHandleSignals signals,
                      MojoDeadline deadline) {
  return MojoWait(handle.value(), signals, deadline);
}

MojoResult WaitMany(
    const std::vector<mojo::Handle>& handles,
    const std::vector<MojoHandleSignals>& signals,
    MojoDeadline deadline) {
  return mojo::WaitMany(handles, signals, deadline);
}

gin::Dictionary CreateMessagePipe(const gin::Arguments& args) {
  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
  dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);

  MojoHandle handle0 = MOJO_HANDLE_INVALID;
  MojoHandle handle1 = MOJO_HANDLE_INVALID;
  MojoResult result = MOJO_RESULT_OK;

  v8::Handle<v8::Value> options_value = args.PeekNext();
  if (options_value.IsEmpty() || options_value->IsNull() ||
      options_value->IsUndefined()) {
    result = MojoCreateMessagePipe(NULL, &handle0, &handle1);
  } else if (options_value->IsObject()) {
    gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
    MojoCreateMessagePipeOptions options;
    // For future struct_size, we can probably infer that from the presence of
    // properties in options_dict. For now, it's always 8.
    options.struct_size = 8;
    // Ideally these would be optional. But the interface makes it hard to
    // typecheck them then.
    if (!options_dict.Get("flags", &options.flags)) {
      return dictionary;
    }

    result = MojoCreateMessagePipe(&options, &handle0, &handle1);
  } else {
      return dictionary;
  }

  CHECK_EQ(MOJO_RESULT_OK, result);

  dictionary.Set("result", result);
  dictionary.Set("handle0", mojo::Handle(handle0));
  dictionary.Set("handle1", mojo::Handle(handle1));
  return dictionary;
}

MojoResult WriteMessage(
    mojo::Handle handle,
    const gin::ArrayBufferView& buffer,
    const std::vector<gin::Handle<HandleWrapper> >& handles,
    MojoWriteMessageFlags flags) {
  std::vector<MojoHandle> raw_handles(handles.size());
  for (size_t i = 0; i < handles.size(); ++i)
    raw_handles[i] = handles[i]->get().value();
  MojoResult rv = MojoWriteMessage(handle.value(),
                          buffer.bytes(),
                          static_cast<uint32_t>(buffer.num_bytes()),
                          raw_handles.empty() ? NULL : &raw_handles[0],
                          static_cast<uint32_t>(raw_handles.size()),
                          flags);
  // MojoWriteMessage takes ownership of the handles upon success, so
  // release them here.
  if (rv == MOJO_RESULT_OK) {
    for (size_t i = 0; i < handles.size(); ++i)
      ignore_result(handles[i]->release());
  }
  return rv;
}

gin::Dictionary ReadMessage(const gin::Arguments& args,
                            mojo::Handle handle,
                            MojoReadMessageFlags flags) {
  uint32_t num_bytes = 0;
  uint32_t num_handles = 0;
  MojoResult result = MojoReadMessage(
      handle.value(), NULL, &num_bytes, NULL, &num_handles, flags);
  if (result != MOJO_RESULT_RESOURCE_EXHAUSTED) {
    gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
    dictionary.Set("result", result);
    return dictionary;
  }

  v8::Handle<v8::ArrayBuffer> array_buffer =
      v8::ArrayBuffer::New(args.isolate(), num_bytes);
  std::vector<mojo::Handle> handles(num_handles);

  gin::ArrayBuffer buffer;
  ConvertFromV8(args.isolate(), array_buffer, &buffer);
  CHECK(buffer.num_bytes() == num_bytes);

  result = MojoReadMessage(handle.value(),
                           buffer.bytes(),
                           &num_bytes,
                           handles.empty() ? NULL :
                               reinterpret_cast<MojoHandle*>(&handles[0]),
                           &num_handles,
                           flags);

  CHECK(buffer.num_bytes() == num_bytes);
  CHECK(handles.size() == num_handles);

  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
  dictionary.Set("result", result);
  dictionary.Set("buffer", array_buffer);
  dictionary.Set("handles", handles);
  return dictionary;
}

gin::Dictionary CreateDataPipe(const gin::Arguments& args) {
  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
  dictionary.Set("result", MOJO_RESULT_INVALID_ARGUMENT);

  MojoHandle producer_handle = MOJO_HANDLE_INVALID;
  MojoHandle consumer_handle = MOJO_HANDLE_INVALID;
  MojoResult result = MOJO_RESULT_OK;

  v8::Handle<v8::Value> options_value = args.PeekNext();
  if (options_value.IsEmpty() || options_value->IsNull() ||
      options_value->IsUndefined()) {
    result = MojoCreateDataPipe(NULL, &producer_handle, &consumer_handle);
  } else if (options_value->IsObject()) {
    gin::Dictionary options_dict(args.isolate(), options_value->ToObject());
    MojoCreateDataPipeOptions options;
    // For future struct_size, we can probably infer that from the presence of
    // properties in options_dict. For now, it's always 16.
    options.struct_size = 16;
    // Ideally these would be optional. But the interface makes it hard to
    // typecheck them then.
    if (!options_dict.Get("flags", &options.flags) ||
        !options_dict.Get("elementNumBytes", &options.element_num_bytes) ||
        !options_dict.Get("capacityNumBytes", &options.capacity_num_bytes)) {
      return dictionary;
    }

    result = MojoCreateDataPipe(&options, &producer_handle, &consumer_handle);
  } else {
    return dictionary;
  }

  CHECK_EQ(MOJO_RESULT_OK, result);

  dictionary.Set("result", result);
  dictionary.Set("producerHandle", mojo::Handle(producer_handle));
  dictionary.Set("consumerHandle", mojo::Handle(consumer_handle));
  return dictionary;
}

gin::Dictionary WriteData(const gin::Arguments& args,
                          mojo::Handle handle,
                          const gin::ArrayBufferView& buffer,
                          MojoWriteDataFlags flags) {
  uint32_t num_bytes = static_cast<uint32_t>(buffer.num_bytes());
  MojoResult result =
      MojoWriteData(handle.value(), buffer.bytes(), &num_bytes, flags);
  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
  dictionary.Set("result", result);
  dictionary.Set("numBytes", num_bytes);
  return dictionary;
}

gin::Dictionary ReadData(const gin::Arguments& args,
                         mojo::Handle handle,
                         MojoReadDataFlags flags) {
  uint32_t num_bytes = 0;
  MojoResult result = MojoReadData(
      handle.value(), NULL, &num_bytes, MOJO_READ_DATA_FLAG_QUERY);
  if (result != MOJO_RESULT_OK) {
    gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
    dictionary.Set("result", result);
    return dictionary;
  }

  v8::Handle<v8::ArrayBuffer> array_buffer =
      v8::ArrayBuffer::New(args.isolate(), num_bytes);
  gin::ArrayBuffer buffer;
  ConvertFromV8(args.isolate(), array_buffer, &buffer);
  CHECK_EQ(num_bytes, buffer.num_bytes());

  result = MojoReadData(handle.value(), buffer.bytes(), &num_bytes, flags);
  CHECK_EQ(num_bytes, buffer.num_bytes());

  gin::Dictionary dictionary = gin::Dictionary::CreateEmpty(args.isolate());
  dictionary.Set("result", result);
  dictionary.Set("buffer", array_buffer);
  return dictionary;
}

// Asynchronously read all of the data available for the specified data pipe
// consumer handle until the remote handle is closed or an error occurs. A
// Promise is returned whose settled value is an object like this:
// {result: core.RESULT_OK, buffer: dataArrayBuffer}. If the read failed,
// then the Promise is rejected, the result will be the actual error code,
// and the buffer will contain whatever was read before the error occurred.
// The drainData data pipe handle argument is closed automatically.

v8::Handle<v8::Value> DoDrainData(gin::Arguments* args,
                                  gin::Handle<HandleWrapper> handle) {
  return (new DrainData(args->isolate(), handle->release()))->GetPromise();
}

gin::WrapperInfo g_wrapper_info = { gin::kEmbedderNativeGin };

}  // namespace

const char Core::kModuleName[] = "mojo/public/js/bindings/core";

v8::Local<v8::Value> Core::GetModule(v8::Isolate* isolate) {
  gin::PerIsolateData* data = gin::PerIsolateData::From(isolate);
  v8::Local<v8::ObjectTemplate> templ = data->GetObjectTemplate(
      &g_wrapper_info);

  if (templ.IsEmpty()) {
     templ = gin::ObjectTemplateBuilder(isolate)
        // TODO(mpcomplete): Should these just be methods on the JS Handle
        // object?
        .SetMethod("close", CloseHandle)
        .SetMethod("wait", WaitHandle)
        .SetMethod("waitMany", WaitMany)
        .SetMethod("createMessagePipe", CreateMessagePipe)
        .SetMethod("writeMessage", WriteMessage)
        .SetMethod("readMessage", ReadMessage)
        .SetMethod("createDataPipe", CreateDataPipe)
        .SetMethod("writeData", WriteData)
        .SetMethod("readData", ReadData)
        .SetMethod("drainData", DoDrainData)

        .SetValue("RESULT_OK", MOJO_RESULT_OK)
        .SetValue("RESULT_CANCELLED", MOJO_RESULT_CANCELLED)
        .SetValue("RESULT_UNKNOWN", MOJO_RESULT_UNKNOWN)
        .SetValue("RESULT_INVALID_ARGUMENT", MOJO_RESULT_INVALID_ARGUMENT)
        .SetValue("RESULT_DEADLINE_EXCEEDED", MOJO_RESULT_DEADLINE_EXCEEDED)
        .SetValue("RESULT_NOT_FOUND", MOJO_RESULT_NOT_FOUND)
        .SetValue("RESULT_ALREADY_EXISTS", MOJO_RESULT_ALREADY_EXISTS)
        .SetValue("RESULT_PERMISSION_DENIED", MOJO_RESULT_PERMISSION_DENIED)
        .SetValue("RESULT_RESOURCE_EXHAUSTED", MOJO_RESULT_RESOURCE_EXHAUSTED)
        .SetValue("RESULT_FAILED_PRECONDITION", MOJO_RESULT_FAILED_PRECONDITION)
        .SetValue("RESULT_ABORTED", MOJO_RESULT_ABORTED)
        .SetValue("RESULT_OUT_OF_RANGE", MOJO_RESULT_OUT_OF_RANGE)
        .SetValue("RESULT_UNIMPLEMENTED", MOJO_RESULT_UNIMPLEMENTED)
        .SetValue("RESULT_INTERNAL", MOJO_RESULT_INTERNAL)
        .SetValue("RESULT_UNAVAILABLE", MOJO_RESULT_UNAVAILABLE)
        .SetValue("RESULT_DATA_LOSS", MOJO_RESULT_DATA_LOSS)
        .SetValue("RESULT_BUSY", MOJO_RESULT_BUSY)
        .SetValue("RESULT_SHOULD_WAIT", MOJO_RESULT_SHOULD_WAIT)

        .SetValue("DEADLINE_INDEFINITE", MOJO_DEADLINE_INDEFINITE)

        .SetValue("HANDLE_SIGNAL_NONE", MOJO_HANDLE_SIGNAL_NONE)
        .SetValue("HANDLE_SIGNAL_READABLE", MOJO_HANDLE_SIGNAL_READABLE)
        .SetValue("HANDLE_SIGNAL_WRITABLE", MOJO_HANDLE_SIGNAL_WRITABLE)

        .SetValue("CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE",
                  MOJO_CREATE_MESSAGE_PIPE_OPTIONS_FLAG_NONE)

        .SetValue("WRITE_MESSAGE_FLAG_NONE", MOJO_WRITE_MESSAGE_FLAG_NONE)

        .SetValue("READ_MESSAGE_FLAG_NONE", MOJO_READ_MESSAGE_FLAG_NONE)
        .SetValue("READ_MESSAGE_FLAG_MAY_DISCARD",
                  MOJO_READ_MESSAGE_FLAG_MAY_DISCARD)

        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_NONE",
                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_NONE)
        .SetValue("CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD",
                  MOJO_CREATE_DATA_PIPE_OPTIONS_FLAG_MAY_DISCARD)

        .SetValue("WRITE_DATA_FLAG_NONE", MOJO_WRITE_DATA_FLAG_NONE)
        .SetValue("WRITE_DATA_FLAG_ALL_OR_NONE",
                  MOJO_WRITE_DATA_FLAG_ALL_OR_NONE)

        .SetValue("READ_DATA_FLAG_NONE", MOJO_READ_DATA_FLAG_NONE)
        .SetValue("READ_DATA_FLAG_ALL_OR_NONE",
                  MOJO_READ_DATA_FLAG_ALL_OR_NONE)
        .SetValue("READ_DATA_FLAG_DISCARD", MOJO_READ_DATA_FLAG_DISCARD)
        .SetValue("READ_DATA_FLAG_QUERY", MOJO_READ_DATA_FLAG_QUERY)
        .Build();

    data->SetObjectTemplate(&g_wrapper_info, templ);
  }

  return templ->NewInstance();
}

}  // namespace js
}  // namespace mojo
