// 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 MojoSystemImplGetRights(MojoSystemImpl system,
                                   MojoHandle handle,
                                   MojoHandleRights* rights) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->GetRights(handle, MakeUserPointer(rights));
}

MojoResult MojoSystemImplDuplicateHandleWithReducedRights(
    MojoSystemImpl system,
    MojoHandle handle,
    MojoHandleRights rights_to_remove,
    MojoHandle* new_handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->DuplicateHandleWithReducedRights(handle, rights_to_remove,
                                                MakeUserPointer(new_handle));
}

MojoResult MojoSystemImplDuplicateHandle(MojoSystemImpl system,
                                         MojoHandle handle,
                                         MojoHandle* new_handle) {
  mojo::system::Core* core = static_cast<mojo::system::Core*>(system);
  DCHECK(core);
  return core->DuplicateHandleWithReducedRights(handle, MOJO_HANDLE_RIGHT_NONE,
                                                MakeUserPointer(new_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"
