// 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.

{{generator_warning}}

#include "{{bindings_dir}}/mojo_syscall.h"

#include <stdio.h>

#include "mojo/public/c/system/core.h"
#include "mojo/public/platform/native/system_impl_private.h"
#include "{{bindings_dir}}/mojo_syscall_internal.h"
#include "native_client/src/public/chrome_main.h"
#include "native_client/src/public/nacl_app.h"
#include "native_client/src/trusted/desc/nacl_desc_custom.h"

MojoHandle g_mojo_handle = MOJO_HANDLE_INVALID;
MojoSystemImpl g_mojo_system = nullptr;

namespace {

MojoResult _MojoGetInitialHandle(MojoHandle* handle) {
  *handle = g_mojo_handle;
  return MOJO_RESULT_OK;
}

void MojoDescDestroy(void* handle) {
}

ssize_t MojoDescSendMsg(void* handle,
                        const struct NaClImcTypedMsgHdr* msg,
                        int flags) {
  struct NaClApp* nap = static_cast<struct NaClApp*>(handle);

  if (msg->iov_length != 1 || msg->ndesc_length != 0) {
    return -1;
  }

  uint32_t volatile* params = static_cast<uint32_t volatile*>(msg->iov[0].base);
  size_t num_params = msg->iov[0].length / sizeof(*params);

  if (num_params < 1) {
    return -1;
  }

  uint32_t msg_type = params[0];
  switch (msg_type) {
{{body}}
  }

  return -1;
}

ssize_t MojoDescRecvMsg(void* handle,
                        struct NaClImcTypedMsgHdr* msg,
                        int flags) {
  return -1;
}

struct NaClDesc* MakeMojoDesc(struct NaClApp* nap) {
  struct NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
  funcs.Destroy = MojoDescDestroy;
  funcs.SendMsg = MojoDescSendMsg;
  funcs.RecvMsg = MojoDescRecvMsg;
  return NaClDescMakeCustomDesc(nap, &funcs);
}

void MojoDisabledDescDestroy(void* handle) {
}

ssize_t MojoDisabledDescSendMsg(void* handle,
                                const struct NaClImcTypedMsgHdr* msg,
                                int flags) {
  fprintf(stderr, "Mojo is not currently supported.");
  abort();
}

ssize_t MojoDisabledDescRecvMsg(void* handle,
                                struct NaClImcTypedMsgHdr* msg,
                                int flags) {
  fprintf(stderr, "Mojo is not currently supported.");
  abort();
}

struct NaClDesc* MakeDisabledMojoDesc(struct NaClApp* nap) {
  struct NaClDescCustomFuncs funcs = NACL_DESC_CUSTOM_FUNCS_INITIALIZER;
  funcs.Destroy = MojoDisabledDescDestroy;
  funcs.SendMsg = MojoDisabledDescSendMsg;
  funcs.RecvMsg = MojoDisabledDescRecvMsg;
  return NaClDescMakeCustomDesc(nap, &funcs);
}

} // namespace

// The value for this FD must not conflict with uses inside Chromium. However,
// mojo/nacl doesn't depend on any Chromium headers, so we can't use a #define
// from there.
#define NACL_MOJO_DESC (NACL_CHROME_DESC_BASE + 3)

MojoResult InjectMojo(struct NaClApp* nap, MojoHandle handle) {
  NaClAppSetDesc(nap, NACL_MOJO_DESC, MakeMojoDesc(nap));
  g_mojo_system = MojoSystemImplCreateImpl();
  return MojoSystemImplTransferHandle(MojoSystemImplGetDefaultImpl(), handle,
                                      g_mojo_system, &g_mojo_handle);
}

void InjectDisabledMojo(struct NaClApp* nap) {
  NaClAppSetDesc(nap, NACL_MOJO_DESC, MakeDisabledMojoDesc(nap));
}
