// Copyright 2015 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 "base/logging.h"
#include "mojo/edk/embedder/embedder_internal.h"
#include "mojo/edk/system/core.h"
#include "mojo/edk/system/dispatcher.h"
#include "mojo/edk/system/handle.h"
#include "mojo/edk/util/ref_ptr.h"
#include "mojo/public/c/system/buffer.h"
#include "mojo/public/c/system/data_pipe.h"
#include "mojo/public/c/system/handle.h"
#include "mojo/public/c/system/message_pipe.h"
#include "mojo/public/c/system/result.h"
#include "mojo/public/c/system/time.h"
#include "mojo/public/c/system/wait.h"
#include "mojo/public/platform/native/system_impl_private.h"

using mojo::embedder::internal::g_core;
using mojo::system::Core;
using mojo::system::Dispatcher;
using mojo::system::Handle;
using mojo::system::MakeUserPointer;
using mojo::util::RefPtr;

// Definitions of the system functions, but with an explicit parameter for the
// core object rather than using the default singleton. Also includes functions
// for manipulating core objects.
extern "C" {

MojoSystemImpl MojoSystemImplGetDefaultImpl() {
  return static_cast<MojoSystemImpl>(g_core);
}

MojoSystemImpl MojoSystemImplCreateImpl() {
  Core* created_core = new Core(g_core->platform_support());
  return static_cast<MojoSystemImpl>(created_core);
}

MojoResult MojoSystemImplTransferHandle(MojoSystemImpl from_system,
                                        MojoHandle handle,
                                        MojoSystemImpl to_system,
                                        MojoHandle* result_handle) {
  Core* from_core = static_cast<Core*>(from_system);
  if (from_core == nullptr)
    return MOJO_RESULT_INVALID_ARGUMENT;

  if (handle == MOJO_HANDLE_INVALID)
    return MOJO_RESULT_INVALID_ARGUMENT;

  Core* to_core = static_cast<Core*>(to_system);
  if (to_core == nullptr)
    return MOJO_RESULT_INVALID_ARGUMENT;

  if (result_handle == nullptr)
    return MOJO_RESULT_INVALID_ARGUMENT;

  Handle h;
  MojoResult result = from_core->GetAndRemoveHandle(handle, &h);
  if (result != MOJO_RESULT_OK)
    return result;

  MojoHandle created_handle =
      to_core->AddHandle(Handle(h.dispatcher.Clone(), h.rights));
  if (created_handle == MOJO_HANDLE_INVALID) {
    // The handle has been lost, unfortunately. There's no guarentee we can put
    // it back where it came from, or get the original ID back. Holding locks
    // for multiple cores risks deadlock, so that isn't a solution. This case
    // should not happen for reasonable uses of this API, however.
    // TODO(vtl): This behaviour is pretty crappy. This can be fixed by marking
    // the original handle as busy and only removing it on success, though
    // that'd require some work.
    LOG(ERROR) << "Could not transfer handle";
    h.dispatcher->Close();
    return MOJO_RESULT_RESOURCE_EXHAUSTED;
  }

  MakeUserPointer(result_handle).Put(created_handle);
  return MOJO_RESULT_OK;
}

MojoTimeTicks MojoSystemImplGetTimeTicksNow(MojoSystemImpl system) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->GetTimeTicksNow();
}

MojoResult MojoSystemImplClose(MojoSystemImpl system, MojoHandle handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->Close(handle);
}

MojoResult MojoSystemImplWait(MojoSystemImpl system,
                              MojoHandle handle,
                              MojoHandleSignals signals,
                              MojoDeadline deadline,
                              MojoHandleSignalsState* signals_state) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->Wait(handle, signals, deadline, MakeUserPointer(signals_state));
}

MojoResult MojoSystemImplWaitMany(MojoSystemImpl system,
                                  const MojoHandle* handles,
                                  const MojoHandleSignals* signals,
                                  uint32_t num_handles,
                                  MojoDeadline deadline,
                                  uint32_t* result_index,
                                  MojoHandleSignalsState* signals_states) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->WaitMany(MakeUserPointer(handles), MakeUserPointer(signals),
                        num_handles, deadline, MakeUserPointer(result_index),
                        MakeUserPointer(signals_states));
}

MojoResult MojoSystemImplCreateMessagePipe(
    MojoSystemImpl system,
    const MojoCreateMessagePipeOptions* options,
    MojoHandle* message_pipe_handle0,
    MojoHandle* message_pipe_handle1) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->CreateMessagePipe(MakeUserPointer(options),
                                 MakeUserPointer(message_pipe_handle0),
                                 MakeUserPointer(message_pipe_handle1));
}

MojoResult MojoSystemImplWriteMessage(MojoSystemImpl system,
                                      MojoHandle message_pipe_handle,
                                      const void* bytes,
                                      uint32_t num_bytes,
                                      const MojoHandle* handles,
                                      uint32_t num_handles,
                                      MojoWriteMessageFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->WriteMessage(message_pipe_handle, MakeUserPointer(bytes),
                            num_bytes, MakeUserPointer(handles), num_handles,
                            flags);
}

MojoResult MojoSystemImplReadMessage(MojoSystemImpl system,
                                     MojoHandle message_pipe_handle,
                                     void* bytes,
                                     uint32_t* num_bytes,
                                     MojoHandle* handles,
                                     uint32_t* num_handles,
                                     MojoReadMessageFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->ReadMessage(message_pipe_handle, MakeUserPointer(bytes),
                           MakeUserPointer(num_bytes), MakeUserPointer(handles),
                           MakeUserPointer(num_handles), flags);
}

MojoResult MojoSystemImplCreateDataPipe(
    MojoSystemImpl system,
    const MojoCreateDataPipeOptions* options,
    MojoHandle* data_pipe_producer_handle,
    MojoHandle* data_pipe_consumer_handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->CreateDataPipe(MakeUserPointer(options),
                              MakeUserPointer(data_pipe_producer_handle),
                              MakeUserPointer(data_pipe_consumer_handle));
}

MojoResult MojoSystemImplSetDataPipeProducerOptions(
    MojoSystemImpl system,
    MojoHandle data_pipe_producer_handle,
    const struct MojoDataPipeProducerOptions* options) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->SetDataPipeProducerOptions(data_pipe_producer_handle,
                                          MakeUserPointer(options));
}

MojoResult MojoSystemImplGetDataPipeProducerOptions(
    MojoSystemImpl system,
    MojoHandle data_pipe_producer_handle,
    struct MojoDataPipeProducerOptions* options,
    uint32_t options_num_bytes) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->GetDataPipeProducerOptions(
      data_pipe_producer_handle, MakeUserPointer(options), options_num_bytes);
}

MojoResult MojoSystemImplWriteData(MojoSystemImpl system,
                                   MojoHandle data_pipe_producer_handle,
                                   const void* elements,
                                   uint32_t* num_elements,
                                   MojoWriteDataFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->WriteData(data_pipe_producer_handle, MakeUserPointer(elements),
                         MakeUserPointer(num_elements), flags);
}

MojoResult MojoSystemImplBeginWriteData(MojoSystemImpl system,
                                        MojoHandle data_pipe_producer_handle,
                                        void** buffer,
                                        uint32_t* buffer_num_elements,
                                        MojoWriteDataFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->BeginWriteData(data_pipe_producer_handle,
                              MakeUserPointer(buffer),
                              MakeUserPointer(buffer_num_elements), flags);
}

MojoResult MojoSystemImplEndWriteData(MojoSystemImpl system,
                                      MojoHandle data_pipe_producer_handle,
                                      uint32_t num_elements_written) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->EndWriteData(data_pipe_producer_handle, num_elements_written);
}

MojoResult MojoSystemImplSetDataPipeConsumerOptions(
    MojoSystemImpl system,
    MojoHandle data_pipe_consumer_handle,
    const struct MojoDataPipeConsumerOptions* options) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->SetDataPipeConsumerOptions(data_pipe_consumer_handle,
                                          MakeUserPointer(options));
}

MojoResult MojoSystemImplGetDataPipeConsumerOptions(
    MojoSystemImpl system,
    MojoHandle data_pipe_consumer_handle,
    struct MojoDataPipeConsumerOptions* options,
    uint32_t options_num_bytes) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->GetDataPipeConsumerOptions(
      data_pipe_consumer_handle, MakeUserPointer(options), options_num_bytes);
}

MojoResult MojoSystemImplReadData(MojoSystemImpl system,
                                  MojoHandle data_pipe_consumer_handle,
                                  void* elements,
                                  uint32_t* num_elements,
                                  MojoReadDataFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->ReadData(data_pipe_consumer_handle, MakeUserPointer(elements),
                        MakeUserPointer(num_elements), flags);
}

MojoResult MojoSystemImplBeginReadData(MojoSystemImpl system,
                                       MojoHandle data_pipe_consumer_handle,
                                       const void** buffer,
                                       uint32_t* buffer_num_elements,
                                       MojoReadDataFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->BeginReadData(data_pipe_consumer_handle, MakeUserPointer(buffer),
                             MakeUserPointer(buffer_num_elements), flags);
}

MojoResult MojoSystemImplEndReadData(MojoSystemImpl system,
                                     MojoHandle data_pipe_consumer_handle,
                                     uint32_t num_elements_read) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->EndReadData(data_pipe_consumer_handle, num_elements_read);
}

MojoResult MojoSystemImplCreateSharedBuffer(
    MojoSystemImpl system,
    const MojoCreateSharedBufferOptions* options,
    uint64_t num_bytes,
    MojoHandle* shared_buffer_handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->CreateSharedBuffer(MakeUserPointer(options), num_bytes,
                                  MakeUserPointer(shared_buffer_handle));
}

MojoResult MojoSystemImplDuplicateBufferHandle(
    MojoSystemImpl system,
    MojoHandle buffer_handle,
    const MojoDuplicateBufferHandleOptions* options,
    MojoHandle* new_buffer_handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->DuplicateBufferHandle(buffer_handle, MakeUserPointer(options),
                                     MakeUserPointer(new_buffer_handle));
}

MojoResult MojoSystemImplGetBufferInformation(MojoSystemImpl system,
                                              MojoHandle buffer_handle,
                                              MojoBufferInformation* info,
                                              uint32_t info_num_bytes) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->GetBufferInformation(buffer_handle, MakeUserPointer(info),
                                    info_num_bytes);
}

MojoResult MojoSystemImplMapBuffer(MojoSystemImpl system,
                                   MojoHandle buffer_handle,
                                   uint64_t offset,
                                   uint64_t num_bytes,
                                   void** buffer,
                                   MojoMapBufferFlags flags) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->MapBuffer(buffer_handle, offset, num_bytes,
                         MakeUserPointer(buffer), flags);
}

MojoResult MojoSystemImplUnmapBuffer(MojoSystemImpl system, void* buffer) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->UnmapBuffer(MakeUserPointer(buffer));
}

}  // extern "C"
