// 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 <stdio.h>
#include <string.h>
#include <set>
#include <vector>

#include "base/logging.h"
#include "base/macros.h"
#include "base/memory/scoped_ptr.h"
#include "dart/runtime/include/dart_api.h"
#include "mojo/dart/embedder/builtin.h"
#include "mojo/dart/embedder/mojo_dart_state.h"
#include "mojo/public/c/system/core.h"
#include "mojo/public/cpp/system/core.h"

namespace mojo {
namespace dart {

#define MOJO_NATIVE_LIST(V)                \
  V(MojoSharedBuffer_Create, 2)            \
  V(MojoSharedBuffer_Duplicate, 2)         \
  V(MojoSharedBuffer_Map, 5)               \
  V(MojoSharedBuffer_Unmap, 1)             \
  V(MojoDataPipe_Create, 3)                \
  V(MojoDataPipe_WriteData, 4)             \
  V(MojoDataPipe_BeginWriteData, 3)        \
  V(MojoDataPipe_EndWriteData, 2)          \
  V(MojoDataPipe_ReadData, 4)              \
  V(MojoDataPipe_BeginReadData, 3)         \
  V(MojoDataPipe_EndReadData, 2)           \
  V(MojoMessagePipe_Create, 1)             \
  V(MojoMessagePipe_Write, 5)              \
  V(MojoMessagePipe_Read, 5)               \
  V(Mojo_GetTimeTicksNow, 0)               \
  V(MojoHandle_Close, 1)                   \
  V(MojoHandle_Wait, 3)                    \
  V(MojoHandle_Register, 2)                \
  V(MojoHandle_WaitMany, 3)                \
  V(MojoHandleWatcher_GrowStateArrays, 1)  \
  V(MojoHandleWatcher_WaitMany, 2)         \
  V(MojoHandleWatcher_SendControlData, 4)  \
  V(MojoHandleWatcher_RecvControlData, 1)  \
  V(MojoHandleWatcher_SetControlHandle, 1) \
  V(MojoHandleWatcher_GetControlHandle, 0)

MOJO_NATIVE_LIST(DECLARE_FUNCTION);

static struct NativeEntries {
  const char* name;
  Dart_NativeFunction function;
  int argument_count;
} MojoEntries[] = {MOJO_NATIVE_LIST(REGISTER_FUNCTION)};

Dart_NativeFunction MojoNativeLookup(Dart_Handle name,
                                     int argument_count,
                                     bool* auto_setup_scope) {
  const char* function_name = nullptr;
  Dart_Handle result = Dart_StringToCString(name, &function_name);
  DART_CHECK_VALID(result);
  DCHECK(function_name != nullptr);
  DCHECK(auto_setup_scope != nullptr);
  *auto_setup_scope = true;
  size_t num_entries = arraysize(MojoEntries);
  for (size_t i = 0; i < num_entries; ++i) {
    const struct NativeEntries& entry = MojoEntries[i];
    if (!strcmp(function_name, entry.name) &&
        (entry.argument_count == argument_count)) {
      return entry.function;
    }
  }
  return nullptr;
}

const uint8_t* MojoNativeSymbol(Dart_NativeFunction nf) {
  size_t num_entries = arraysize(MojoEntries);
  for (size_t i = 0; i < num_entries; ++i) {
    const struct NativeEntries& entry = MojoEntries[i];
    if (entry.function == nf) {
      return reinterpret_cast<const uint8_t*>(entry.name);
    }
  }
  return nullptr;
}

static void SetNullReturn(Dart_NativeArguments arguments) {
  Dart_SetReturnValue(arguments, Dart_Null());
}

static void SetInvalidArgumentReturn(Dart_NativeArguments arguments) {
  Dart_SetIntegerReturnValue(
      arguments, static_cast<int64_t>(MOJO_RESULT_INVALID_ARGUMENT));
}

static Dart_Handle SignalsStateToDart(const MojoHandleSignalsState& state) {
  Dart_Handle list = Dart_NewList(2);
  Dart_Handle arg0 = Dart_NewInteger(state.satisfied_signals);
  Dart_Handle arg1 = Dart_NewInteger(state.satisfiable_signals);
  Dart_ListSetAt(list, 0, arg0);
  Dart_ListSetAt(list, 1, arg1);
  return list;
}

#define CHECK_INTEGER_ARGUMENT(args, num, result, failure)                     \
  {                                                                            \
    Dart_Handle __status;                                                      \
    __status = Dart_GetNativeIntegerArgument(args, num, result);               \
    if (Dart_IsError(__status)) {                                              \
      Set##failure##Return(arguments);                                         \
      return;                                                                  \
    }                                                                          \
  }                                                                            \

struct CloserCallbackPeer {
  MojoHandle handle;
};

static void MojoHandleCloserCallback(void* isolate_data,
                                     Dart_WeakPersistentHandle handle,
                                     void* peer) {
  CloserCallbackPeer* callback_peer =
      reinterpret_cast<CloserCallbackPeer*>(peer);
  if (callback_peer->handle != MOJO_HANDLE_INVALID) {
    MojoResult res = MojoClose(callback_peer->handle);
    if (res == MOJO_RESULT_OK) {
      // If this finalizer callback successfully closes a handle, it means that
      // the handle has leaked from the Dart code, which is an error.
      LOG(ERROR) << "Handle Finalizer closing handle:\n\tisolate: "
                 << "\n\thandle: " << callback_peer->handle;
    }
  }
  delete callback_peer;
}

// Setup a weak persistent handle for a MojoHandle that calls MojoClose on the
// handle when the MojoHandle is GC'd or the VM is going down.
void MojoHandle_Register(Dart_NativeArguments arguments) {
  Dart_Handle mojo_handle_instance = Dart_GetNativeArgument(arguments, 0);
  if (!Dart_IsInstance(mojo_handle_instance)) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  int64_t raw_handle = static_cast<int64_t>(MOJO_HANDLE_INVALID);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &raw_handle, InvalidArgument);
  if (raw_handle == static_cast<int64_t>(MOJO_HANDLE_INVALID)) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  // Add the handle to this isolate's set.
  MojoHandle handle = static_cast<MojoHandle>(raw_handle);
  auto isolate_data = MojoDartState::Current();
  DCHECK(isolate_data != nullptr);
  isolate_data->unclosed_handles().insert(handle);

  // Set up a finalizer.
  CloserCallbackPeer* callback_peer = new CloserCallbackPeer();
  callback_peer->handle = handle;
  Dart_NewWeakPersistentHandle(mojo_handle_instance,
                               reinterpret_cast<void*>(callback_peer),
                               sizeof(CloserCallbackPeer),
                               MojoHandleCloserCallback);
  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
}

void Mojo_GetTimeTicksNow(Dart_NativeArguments arguments) {
  MojoTimeTicks ticks = MojoGetTimeTicksNow();
  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(ticks));
}

void MojoHandle_Close(Dart_NativeArguments arguments) {
  int64_t raw_handle;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &raw_handle, InvalidArgument);

  // Remove the handle from this isolate's set.
  MojoHandle handle = static_cast<MojoHandle>(raw_handle);
  auto isolate_data = MojoDartState::Current();
  DCHECK(isolate_data != nullptr);
  isolate_data->unclosed_handles().erase(handle);

  MojoResult res = MojoClose(handle);

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoHandle_Wait(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t signals = 0;
  int64_t deadline = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &signals, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);

  MojoHandleSignalsState state;
  MojoResult r = mojo::Wait(mojo::Handle(static_cast<MojoHandle>(handle)),
                            static_cast<MojoHandleSignals>(signals),
                            static_cast<MojoDeadline>(deadline), &state);

  // The return value is structured as a list of length 2:
  // [0] MojoResult
  // [1] MojoHandleSignalsState. (may be null)
  Dart_Handle list = Dart_NewList(2);
  Dart_ListSetAt(list, 0, Dart_NewInteger(r));
  if (mojo::WaitManyResult(r).AreSignalsStatesValid()) {
    Dart_ListSetAt(list, 1, SignalsStateToDart(state));
  } else {
    Dart_ListSetAt(list, 1, Dart_Null());
  }
  Dart_SetReturnValue(arguments, list);
}

void MojoHandle_WaitMany(Dart_NativeArguments arguments) {
  int64_t deadline = 0;
  Dart_Handle handles = Dart_GetNativeArgument(arguments, 0);
  Dart_Handle signals = Dart_GetNativeArgument(arguments, 1);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &deadline, InvalidArgument);

  if (!Dart_IsList(handles) || !Dart_IsList(signals)) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  intptr_t handles_len = 0;
  intptr_t signals_len = 0;
  Dart_ListLength(handles, &handles_len);
  Dart_ListLength(signals, &signals_len);
  if (handles_len != signals_len) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  std::vector<mojo::Handle> mojo_handles(handles_len);
  std::vector<MojoHandleSignals> mojo_signals(handles_len);

  for (int i = 0; i < handles_len; i++) {
    Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
    Dart_Handle dart_signal = Dart_ListGetAt(signals, i);
    if (!Dart_IsInteger(dart_handle) || !Dart_IsInteger(dart_signal)) {
      SetInvalidArgumentReturn(arguments);
      return;
    }
    int64_t mojo_handle = 0;
    int64_t mojo_signal = 0;
    Dart_IntegerToInt64(dart_handle, &mojo_handle);
    Dart_IntegerToInt64(dart_signal, &mojo_signal);
    mojo_handles[i] = mojo::Handle(mojo_handle);
    mojo_signals[i] = static_cast<MojoHandleSignals>(mojo_signal);
  }

  std::vector<MojoHandleSignalsState> states(handles_len);
  mojo::WaitManyResult wmr = mojo::WaitMany(
      mojo_handles, mojo_signals, static_cast<MojoDeadline>(deadline), &states);

  // The return value is structured as a list of length 3:
  // [0] MojoResult
  // [1] index of handle that caused a return (may be null)
  // [2] list of MojoHandleSignalsState. (may be null)
  Dart_Handle list = Dart_NewList(3);
  Dart_ListSetAt(list, 0, Dart_NewInteger(wmr.result));
  if (wmr.IsIndexValid())
    Dart_ListSetAt(list, 1, Dart_NewInteger(wmr.index));
  else
    Dart_ListSetAt(list, 1, Dart_Null());
  if (wmr.AreSignalsStatesValid()) {
    Dart_Handle stateList = Dart_NewList(handles_len);
    for (int i = 0; i < handles_len; i++) {
      Dart_ListSetAt(stateList, i, SignalsStateToDart(states[i]));
    }
    Dart_ListSetAt(list, 2, stateList);
  } else {
    Dart_ListSetAt(list, 2, Dart_Null());
  }
  Dart_SetReturnValue(arguments, list);
}

void MojoSharedBuffer_Create(Dart_NativeArguments arguments) {
  int64_t num_bytes = 0;
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &num_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);

  MojoCreateSharedBufferOptions options;
  options.struct_size = sizeof(MojoCreateSharedBufferOptions);
  options.flags = static_cast<MojoCreateSharedBufferOptionsFlags>(flags);

  MojoHandle out = MOJO_HANDLE_INVALID;;
  MojoResult res = MojoCreateSharedBuffer(
      &options, static_cast<int32_t>(num_bytes), &out);

  Dart_Handle list = Dart_NewList(2);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(out));
  Dart_SetReturnValue(arguments, list);
}

void MojoSharedBuffer_Duplicate(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &flags, Null);

  MojoDuplicateBufferHandleOptions options;
  options.struct_size = sizeof(MojoDuplicateBufferHandleOptions);
  options.flags = static_cast<MojoDuplicateBufferHandleOptionsFlags>(flags);

  MojoHandle out = MOJO_HANDLE_INVALID;;
  MojoResult res = MojoDuplicateBufferHandle(
      static_cast<MojoHandle>(handle), &options, &out);

  Dart_Handle list = Dart_NewList(2);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(out));
  Dart_SetReturnValue(arguments, list);
}

static void MojoBufferUnmapCallback(void* isolate_data,
                                    Dart_WeakPersistentHandle handle,
                                    void* peer) {
  MojoUnmapBuffer(peer);
}

void MojoSharedBuffer_Map(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t offset = 0;
  int64_t num_bytes = 0;
  int64_t flags = 0;
  Dart_Handle mojo_buffer = Dart_GetNativeArgument(arguments, 0);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &handle, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &offset, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 3, &num_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);

  void* out;
  MojoResult res = MojoMapBuffer(static_cast<MojoHandle>(handle),
                                 offset,
                                 num_bytes,
                                 &out,
                                 static_cast<MojoMapBufferFlags>(flags));

  Dart_Handle list = Dart_NewList(2);
  Dart_Handle typed_data;
  if (res == MOJO_RESULT_OK) {
    typed_data = Dart_NewExternalTypedData(
        Dart_TypedData_kByteData, out, num_bytes);
    Dart_NewWeakPersistentHandle(
        mojo_buffer, out, num_bytes, MojoBufferUnmapCallback);
  } else {
    typed_data = Dart_Null();
  }
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, typed_data);
  Dart_SetReturnValue(arguments, list);
}

void MojoSharedBuffer_Unmap(Dart_NativeArguments arguments) {
  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 0);
  if (Dart_GetTypeOfExternalTypedData(typed_data) == Dart_TypedData_kInvalid) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  Dart_TypedData_Type typ;
  void *data;
  intptr_t len;
  Dart_TypedDataAcquireData(typed_data, &typ, &data, &len);
  MojoResult res = MojoUnmapBuffer(data);
  Dart_TypedDataReleaseData(typed_data);

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoDataPipe_Create(Dart_NativeArguments arguments) {
  int64_t element_bytes = 0;
  int64_t capacity_bytes = 0;
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &element_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &capacity_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);

  MojoCreateDataPipeOptions options;
  options.struct_size = sizeof(MojoCreateDataPipeOptions);
  options.flags = static_cast<MojoCreateDataPipeOptionsFlags>(flags);
  options.element_num_bytes = static_cast<uint32_t>(element_bytes);
  options.capacity_num_bytes = static_cast<uint32_t>(capacity_bytes);

  MojoHandle producer = MOJO_HANDLE_INVALID;
  MojoHandle consumer = MOJO_HANDLE_INVALID;
  MojoResult res = MojoCreateDataPipe(&options, &producer, &consumer);

  Dart_Handle list = Dart_NewList(3);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(producer));
  Dart_ListSetAt(list, 2, Dart_NewInteger(consumer));
  Dart_SetReturnValue(arguments, list);
}

void MojoDataPipe_WriteData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);

  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
  if (!Dart_IsTypedData(typed_data)) {
    SetNullReturn(arguments);
    return;
  }

  int64_t num_bytes = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
  if (num_bytes <= 0) {
    SetNullReturn(arguments);
    return;
  }

  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);

  Dart_TypedData_Type type;
  void* data;
  intptr_t data_length;
  Dart_TypedDataAcquireData(typed_data, &type, &data, &data_length);
  uint32_t length = static_cast<uint32_t>(num_bytes);
  MojoResult res = MojoWriteData(
      static_cast<MojoHandle>(handle),
      data,
      &length,
      static_cast<MojoWriteDataFlags>(flags));
  Dart_TypedDataReleaseData(typed_data);

  Dart_Handle list = Dart_NewList(2);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(length));
  Dart_SetReturnValue(arguments, list);
}

void MojoDataPipe_BeginWriteData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t buffer_bytes = 0;
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);

  void* buffer;
  uint32_t size = static_cast<uint32_t>(buffer_bytes);
  MojoResult res = MojoBeginWriteData(
      static_cast<MojoHandle>(handle),
      &buffer,
      &size,
      static_cast<MojoWriteDataFlags>(flags));

  Dart_Handle list = Dart_NewList(2);
  Dart_Handle typed_data;
  if (res == MOJO_RESULT_OK) {
    typed_data = Dart_NewExternalTypedData(
        Dart_TypedData_kByteData, buffer, size);
  } else {
    typed_data = Dart_Null();
  }
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, typed_data);
  Dart_SetReturnValue(arguments, list);
}

void MojoDataPipe_EndWriteData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t num_bytes_written = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_written, InvalidArgument);

  MojoResult res = MojoEndWriteData(
      static_cast<MojoHandle>(handle),
      static_cast<uint32_t>(num_bytes_written));

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoDataPipe_ReadData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);

  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
    SetNullReturn(arguments);
    return;
  }
  // When querying the amount of data available to read from the pipe,
  // null is passed in for typed_data.

  int64_t num_bytes = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);

  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 3, &flags, Null);

  Dart_TypedData_Type typ;
  void* data = nullptr;
  intptr_t bdlen = 0;
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataAcquireData(typed_data, &typ, &data, &bdlen);
  }
  uint32_t len = static_cast<uint32_t>(num_bytes);
  MojoResult res = MojoReadData(
      static_cast<MojoHandle>(handle),
      data,
      &len,
      static_cast<MojoReadDataFlags>(flags));
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataReleaseData(typed_data);
  }

  Dart_Handle list = Dart_NewList(2);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(len));
  Dart_SetReturnValue(arguments, list);
}

void MojoDataPipe_BeginReadData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t buffer_bytes = 0;
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &buffer_bytes, Null);
  CHECK_INTEGER_ARGUMENT(arguments, 2, &flags, Null);

  void* buffer;
  uint32_t size = static_cast<uint32_t>(buffer_bytes);
  MojoResult res = MojoBeginReadData(
      static_cast<MojoHandle>(handle),
      const_cast<const void**>(&buffer),
      &size,
      static_cast<MojoWriteDataFlags>(flags));

  Dart_Handle list = Dart_NewList(2);
  Dart_Handle typed_data;
  if (res == MOJO_RESULT_OK) {
    typed_data = Dart_NewExternalTypedData(
        Dart_TypedData_kByteData, buffer, size);
  } else {
    typed_data = Dart_Null();
  }
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, typed_data);
  Dart_SetReturnValue(arguments, list);
}

void MojoDataPipe_EndReadData(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  int64_t num_bytes_read = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &num_bytes_read, InvalidArgument);

  MojoResult res = MojoEndReadData(
      static_cast<MojoHandle>(handle),
      static_cast<uint32_t>(num_bytes_read));

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoMessagePipe_Create(Dart_NativeArguments arguments) {
  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &flags, Null);

  MojoCreateMessagePipeOptions options;
  options.struct_size = sizeof(MojoCreateMessagePipeOptions);
  options.flags = static_cast<MojoCreateMessagePipeOptionsFlags>(flags);

  MojoHandle end1 = MOJO_HANDLE_INVALID;
  MojoHandle end2 = MOJO_HANDLE_INVALID;
  MojoResult res = MojoCreateMessagePipe(&options, &end1, &end2);

  Dart_Handle list = Dart_NewList(3);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(end1));
  Dart_ListSetAt(list, 2, Dart_NewInteger(end2));
  Dart_SetReturnValue(arguments, list);
}

void MojoMessagePipe_Write(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, InvalidArgument);

  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  int64_t num_bytes = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, InvalidArgument);
  if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
      (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
  if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
    SetInvalidArgumentReturn(arguments);
    return;
  }

  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, InvalidArgument);

  // Grab the data if there is any.
  Dart_TypedData_Type typ;
  void* bytes = nullptr;
  intptr_t bdlen = 0;
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &bdlen);
  }

  // Grab the handles if there are any.
  scoped_ptr<MojoHandle[]> mojo_handles;
  intptr_t handles_len = 0;
  if (!Dart_IsNull(handles)) {
    Dart_ListLength(handles, &handles_len);
    if (handles_len > 0) {
      mojo_handles.reset(new MojoHandle[handles_len]);
    }
    for (int i = 0; i < handles_len; i++) {
      Dart_Handle dart_handle = Dart_ListGetAt(handles, i);
      if (!Dart_IsInteger(dart_handle)) {
        SetInvalidArgumentReturn(arguments);
        return;
      }
      int64_t mojo_handle = 0;
      Dart_IntegerToInt64(dart_handle, &mojo_handle);
      mojo_handles[i] = static_cast<MojoHandle>(mojo_handle);
    }
  }

  MojoResult res = MojoWriteMessage(
      static_cast<MojoHandle>(handle),
      const_cast<const void*>(bytes),
      static_cast<uint32_t>(num_bytes),
      mojo_handles.get(),
      static_cast<uint32_t>(handles_len),
      static_cast<MojoWriteMessageFlags>(flags));

  // Release the data.
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataReleaseData(typed_data);
  }

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoMessagePipe_Read(Dart_NativeArguments arguments) {
  int64_t handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handle, Null);

  Dart_Handle typed_data = Dart_GetNativeArgument(arguments, 1);
  if (!Dart_IsTypedData(typed_data) && !Dart_IsNull(typed_data)) {
    SetNullReturn(arguments);
    return;
  }
  // When querying the amount of data available to read from the pipe,
  // null is passed in for typed_data.

  int64_t num_bytes = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 2, &num_bytes, Null);
  if ((Dart_IsNull(typed_data) && (num_bytes != 0)) ||
      (!Dart_IsNull(typed_data) && (num_bytes <= 0))) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle handles = Dart_GetNativeArgument(arguments, 3);
  if (!Dart_IsList(handles) && !Dart_IsNull(handles)) {
    SetNullReturn(arguments);
    return;
  }

  int64_t flags = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 4, &flags, Null);

  // Grab the data if there is any.
  Dart_TypedData_Type typ;
  void* bytes = nullptr;
  intptr_t byte_data_len = 0;
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataAcquireData(typed_data, &typ, &bytes, &byte_data_len);
  }
  uint32_t blen = static_cast<uint32_t>(num_bytes);

  // Grab the handles if there are any.
  scoped_ptr<MojoHandle[]> mojo_handles;
  intptr_t handles_len = 0;
  if (!Dart_IsNull(handles)) {
    Dart_ListLength(handles, &handles_len);
    mojo_handles.reset(new MojoHandle[handles_len]);
  }
  uint32_t hlen = static_cast<uint32_t>(handles_len);

  MojoResult res = MojoReadMessage(
      static_cast<MojoHandle>(handle),
      bytes,
      &blen,
      mojo_handles.get(),
      &hlen,
      static_cast<MojoReadMessageFlags>(flags));

  // Release the data.
  if (!Dart_IsNull(typed_data)) {
    Dart_TypedDataReleaseData(typed_data);
  }

  if (!Dart_IsNull(handles)) {
    for (int i = 0; i < handles_len; i++) {
      Dart_ListSetAt(handles, i, Dart_NewInteger(mojo_handles[i]));
    }
  }

  Dart_Handle list = Dart_NewList(3);
  Dart_ListSetAt(list, 0, Dart_NewInteger(res));
  Dart_ListSetAt(list, 1, Dart_NewInteger(blen));
  Dart_ListSetAt(list, 2, Dart_NewInteger(hlen));
  Dart_SetReturnValue(arguments, list);
}

struct MojoWaitManyState {
  MojoWaitManyState() {}

  std::vector<uint32_t> handles;
  std::vector<uint32_t> signals;
  std::vector<uint32_t> out_index;
  std::vector<MojoHandleSignalsState> out_signals;

  static MojoWaitManyState* GetInstance();

 private:
  DISALLOW_COPY_AND_ASSIGN(MojoWaitManyState);
};

// This global is safe because it is only accessed by the single handle watcher
// isolate. If multiple handle watcher isolates are ever needed, it will need
// to be replicated.
MojoWaitManyState* MojoWaitManyState::GetInstance() {
  static MojoWaitManyState* state = new MojoWaitManyState;
  return state;
}

void MojoHandleWatcher_GrowStateArrays(Dart_NativeArguments arguments) {
  int64_t new_length;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &new_length, InvalidArgument);

  MojoWaitManyState& handle_watcher_wait_state =
      *MojoWaitManyState::GetInstance();

  handle_watcher_wait_state.handles.resize(new_length);
  handle_watcher_wait_state.signals.resize(new_length);
  handle_watcher_wait_state.out_index.resize(1);
  handle_watcher_wait_state.out_signals.resize(new_length);

  Dart_Handle dart_handles = Dart_NewExternalTypedData(
      Dart_TypedData_kUint32, handle_watcher_wait_state.handles.data(),
      handle_watcher_wait_state.handles.size());
  if (Dart_IsError(dart_handles)) {
    Dart_PropagateError(dart_handles);
  }
  if (Dart_IsNull(dart_handles)) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle dart_signals = Dart_NewExternalTypedData(
      Dart_TypedData_kUint32, handle_watcher_wait_state.signals.data(),
      handle_watcher_wait_state.signals.size());
  if (Dart_IsError(dart_signals)) {
    Dart_PropagateError(dart_signals);
  }
  if (Dart_IsNull(dart_signals)) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle dart_out_index = Dart_NewExternalTypedData(
      Dart_TypedData_kUint32, handle_watcher_wait_state.out_index.data(),
      handle_watcher_wait_state.out_index.size());
  if (Dart_IsError(dart_out_index)) {
    Dart_PropagateError(dart_out_index);
  }
  if (Dart_IsNull(dart_out_index)) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle dart_out_signals = Dart_NewExternalTypedData(
      Dart_TypedData_kUint64, handle_watcher_wait_state.out_signals.data(),
      handle_watcher_wait_state.out_signals.size());
  if (Dart_IsError(dart_out_signals)) {
    Dart_PropagateError(dart_out_signals);
  }
  if (Dart_IsNull(dart_out_signals)) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle list = Dart_NewList(4);
  Dart_ListSetAt(list, 0, dart_handles);
  Dart_ListSetAt(list, 1, dart_signals);
  Dart_ListSetAt(list, 2, dart_out_index);
  Dart_ListSetAt(list, 3, dart_out_signals);
  Dart_SetReturnValue(arguments, list);
}

void MojoHandleWatcher_WaitMany(Dart_NativeArguments arguments) {
  int64_t handles_len = 0;
  int64_t deadline = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &handles_len, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &deadline, InvalidArgument);

  MojoWaitManyState& handle_watcher_wait_state =
      *MojoWaitManyState::GetInstance();

  uint32_t* handles = handle_watcher_wait_state.handles.data();
  uint32_t* signals = handle_watcher_wait_state.signals.data();
  uint32_t* out_index = handle_watcher_wait_state.out_index.data();
  MojoHandleSignalsState* out_signals =
      handle_watcher_wait_state.out_signals.data();

  Dart_IsolateBlocked();
  MojoResult mojo_result = MojoWaitMany(handles, signals, handles_len, deadline,
                                        out_index, out_signals);
  Dart_IsolateUnblocked();

  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(mojo_result));
}

struct ControlData {
  int64_t handle;
  Dart_Port port;
  int64_t data;
};

void MojoHandleWatcher_SendControlData(Dart_NativeArguments arguments) {
  int64_t control_handle = 0;
  int64_t client_handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
  CHECK_INTEGER_ARGUMENT(arguments, 1, &client_handle, InvalidArgument);

  Dart_Handle send_port_handle = Dart_GetNativeArgument(arguments, 2);
  Dart_Port send_port_id = ILLEGAL_PORT;
  if (!Dart_IsNull(send_port_handle)) {
    Dart_Handle result = Dart_SendPortGetId(send_port_handle, &send_port_id);
    if (Dart_IsError(result)) {
      SetInvalidArgumentReturn(arguments);
      return;
    }
  }

  int64_t data = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 3, &data, InvalidArgument);

  ControlData cd;
  cd.handle = client_handle;
  cd.port = send_port_id;
  cd.data = data;
  const void* bytes = reinterpret_cast<const void*>(&cd);
  MojoResult res = MojoWriteMessage(
      control_handle, bytes, sizeof(cd), nullptr, 0, 0);
  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(res));
}

void MojoHandleWatcher_RecvControlData(Dart_NativeArguments arguments) {
  int64_t control_handle = 0;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, Null);

  ControlData cd;
  void* bytes = reinterpret_cast<void*>(&cd);
  uint32_t num_bytes = sizeof(cd);
  uint32_t num_handles = 0;
  MojoResult res = MojoReadMessage(
      control_handle, bytes, &num_bytes, nullptr, &num_handles, 0);
  if (res != MOJO_RESULT_OK) {
    SetNullReturn(arguments);
    return;
  }

  Dart_Handle list = Dart_NewList(3);
  Dart_ListSetAt(list, 0, Dart_NewInteger(cd.handle));
  if (cd.port != ILLEGAL_PORT) {
    Dart_ListSetAt(list, 1, Dart_NewSendPort(cd.port));
  }
  Dart_ListSetAt(list, 2, Dart_NewInteger(cd.data));
  Dart_SetReturnValue(arguments, list);
}

static int64_t mojo_control_handle = MOJO_HANDLE_INVALID;
void MojoHandleWatcher_SetControlHandle(Dart_NativeArguments arguments) {
  int64_t control_handle;
  CHECK_INTEGER_ARGUMENT(arguments, 0, &control_handle, InvalidArgument);
  mojo_control_handle = control_handle;
  Dart_SetIntegerReturnValue(arguments, static_cast<int64_t>(MOJO_RESULT_OK));
}

void MojoHandleWatcher_GetControlHandle(Dart_NativeArguments arguments) {
  Dart_SetIntegerReturnValue(arguments, mojo_control_handle);
}

}  // namespace dart
}  // namespace mojo
