// 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 "mojo/edk/embedder/multiprocess_embedder.h"

#include <atomic>
#include <utility>

#include "base/logging.h"
#include "mojo/edk/embedder/embedder_internal.h"
#include "mojo/edk/embedder/master_process_delegate.h"
#include "mojo/edk/embedder/process_delegate.h"
#include "mojo/edk/embedder/slave_process_delegate.h"
#include "mojo/edk/system/channel.h"
#include "mojo/edk/system/channel_manager.h"
#include "mojo/edk/system/core.h"
#include "mojo/edk/system/handle.h"
#include "mojo/edk/system/ipc_support.h"
#include "mojo/edk/system/message_pipe_dispatcher.h"
#include "mojo/edk/system/raw_channel.h"
#include "mojo/edk/util/ref_ptr.h"

using mojo::platform::PlatformHandleWatcher;
using mojo::platform::ScopedPlatformHandle;
using mojo::platform::TaskRunner;
using mojo::util::RefPtr;

namespace mojo {
namespace embedder {

namespace internal {

// Declared in embedder_internal.h.
system::IPCSupport* g_ipc_support = nullptr;

}  // namespace internal

namespace {

std::atomic<unsigned>* g_make_channel_id_counter = nullptr;

// TODO(vtl): For now, we need this to be thread-safe (since theoretically we
// currently support multiple channel creation threads -- possibly one per
// channel). Eventually, we won't need it to be thread-safe (we'll require a
// single I/O thread), and eventually we won't need it at all. Remember to
// remove the base/atomicops.h include.
system::ChannelId MakeChannelId() {
  DCHECK(g_make_channel_id_counter);
  unsigned new_counter_value = g_make_channel_id_counter->fetch_add(1u) + 1u;
  // Don't allow the counter to wrap.
  CHECK_GT(new_counter_value, 0u);
  // Use "negative" values for these IDs, so that we'll also be able to use
  // "positive" "process identifiers" (see connection_manager.h) as IDs (and
  // they won't conflict). (|system::ChannelId| is a |uint64_t|, so assuming
  // that |unsigned| is 32-bit, we won't run into the process identifiers.)
  return -static_cast<system::ChannelId>(new_counter_value);
}

}  // namespace

void InitIPCSupport(ProcessType process_type,
                    RefPtr<TaskRunner>&& delegate_thread_task_runner,
                    ProcessDelegate* process_delegate,
                    RefPtr<TaskRunner>&& io_task_runner,
                    PlatformHandleWatcher* io_watcher,
                    ScopedPlatformHandle platform_handle) {
  // |Init()| must have already been called.
  DCHECK(internal::g_core);
  // And not |InitIPCSupport()| (without |ShutdownIPCSupport()|).
  DCHECK(!internal::g_ipc_support);
  DCHECK(!g_make_channel_id_counter);

  internal::g_ipc_support = new system::IPCSupport(
      internal::g_platform_support, process_type,
      std::move(delegate_thread_task_runner), process_delegate,
      std::move(io_task_runner), io_watcher, platform_handle.Pass());

  g_make_channel_id_counter = new std::atomic<unsigned>();
}

void ShutdownIPCSupportOnIOThread() {
  DCHECK(internal::g_ipc_support);
  DCHECK(g_make_channel_id_counter);

  internal::g_ipc_support->ShutdownOnIOThread();
  delete internal::g_ipc_support;
  internal::g_ipc_support = nullptr;
  delete g_make_channel_id_counter;
  g_make_channel_id_counter = nullptr;
}

void ShutdownIPCSupport() {
  DCHECK(internal::g_ipc_support);

  internal::g_ipc_support->io_task_runner()->PostTask([]() {
    // Save these before they get nuked by |ShutdownChannelOnIOThread()|.
    RefPtr<TaskRunner> delegate_thread_task_runner(
        internal::g_ipc_support->delegate_thread_task_runner());
    ProcessDelegate* process_delegate =
        internal::g_ipc_support->process_delegate();

    ShutdownIPCSupportOnIOThread();

    delegate_thread_task_runner->PostTask(
        [process_delegate]() { process_delegate->OnShutdownComplete(); });
  });
}

ScopedMessagePipeHandle ConnectToSlave(
    SlaveInfo slave_info,
    ScopedPlatformHandle platform_handle,
    std::function<void()>&& did_connect_to_slave_callback,
    RefPtr<TaskRunner>&& did_connect_to_slave_runner,
    std::string* platform_connection_id,
    ChannelInfo** channel_info) {
  DCHECK(platform_connection_id);
  DCHECK(channel_info);
  DCHECK(internal::g_ipc_support);

  system::ConnectionIdentifier connection_id =
      internal::g_ipc_support->GenerateConnectionIdentifier();
  *platform_connection_id = connection_id.ToString();
  system::ChannelId channel_id = system::kInvalidChannelId;
  RefPtr<system::MessagePipeDispatcher> dispatcher =
      internal::g_ipc_support->ConnectToSlave(
          connection_id, slave_info, platform_handle.Pass(),
          std::move(did_connect_to_slave_callback),
          std::move(did_connect_to_slave_runner), &channel_id);
  *channel_info = new ChannelInfo(channel_id);

  ScopedMessagePipeHandle rv(MessagePipeHandle(internal::g_core->AddHandle(
      system::Handle(std::move(dispatcher),
                     system::MessagePipeDispatcher::kDefaultHandleRights))));
  CHECK(rv.is_valid());
  return rv;
}

ScopedMessagePipeHandle ConnectToMaster(
    const std::string& platform_connection_id,
    std::function<void()>&& did_connect_to_master_callback,
    RefPtr<TaskRunner>&& did_connect_to_master_runner,
    ChannelInfo** channel_info) {
  DCHECK(channel_info);
  DCHECK(internal::g_ipc_support);

  bool ok = false;
  system::ConnectionIdentifier connection_id =
      system::ConnectionIdentifier::FromString(platform_connection_id, &ok);
  CHECK(ok);

  system::ChannelId channel_id = system::kInvalidChannelId;
  RefPtr<system::MessagePipeDispatcher> dispatcher =
      internal::g_ipc_support->ConnectToMaster(
          connection_id, std::move(did_connect_to_master_callback),
          std::move(did_connect_to_master_runner), &channel_id);
  *channel_info = new ChannelInfo(channel_id);

  ScopedMessagePipeHandle rv(MessagePipeHandle(internal::g_core->AddHandle(
      system::Handle(std::move(dispatcher),
                     system::MessagePipeDispatcher::kDefaultHandleRights))));
  CHECK(rv.is_valid());
  return rv;
}

// TODO(vtl): Write tests for this.
ScopedMessagePipeHandle CreateChannelOnIOThread(
    ScopedPlatformHandle platform_handle,
    ChannelInfo** channel_info) {
  DCHECK(platform_handle.is_valid());
  DCHECK(channel_info);
  DCHECK(internal::g_ipc_support);

  system::ChannelManager* channel_manager =
      internal::g_ipc_support->channel_manager();

  *channel_info = new ChannelInfo(MakeChannelId());
  RefPtr<system::MessagePipeDispatcher> dispatcher =
      channel_manager->CreateChannelOnIOThread((*channel_info)->channel_id,
                                               platform_handle.Pass());

  ScopedMessagePipeHandle rv(MessagePipeHandle(internal::g_core->AddHandle(
      system::Handle(std::move(dispatcher),
                     system::MessagePipeDispatcher::kDefaultHandleRights))));
  CHECK(rv.is_valid());
  return rv;
}

ScopedMessagePipeHandle CreateChannel(
    ScopedPlatformHandle platform_handle,
    std::function<void(ChannelInfo*)>&& did_create_channel_callback,
    RefPtr<TaskRunner>&& did_create_channel_runner) {
  DCHECK(platform_handle.is_valid());
  DCHECK(did_create_channel_callback);
  DCHECK(internal::g_ipc_support);

  system::ChannelManager* channel_manager =
      internal::g_ipc_support->channel_manager();

  system::ChannelId channel_id = MakeChannelId();
  // Ownership gets passed back to the caller via |did_create_channel_callback|.
  ChannelInfo* channel_info = new ChannelInfo(channel_id);
  RefPtr<system::MessagePipeDispatcher> dispatcher =
      channel_manager->CreateChannel(
          channel_id, platform_handle.Pass(),
          [did_create_channel_callback, channel_info]() {
            did_create_channel_callback(channel_info);
          },
          std::move(did_create_channel_runner));

  ScopedMessagePipeHandle rv(MessagePipeHandle(internal::g_core->AddHandle(
      system::Handle(std::move(dispatcher),
                     system::MessagePipeDispatcher::kDefaultHandleRights))));
  CHECK(rv.is_valid());
  return rv;
}

// TODO(vtl): Write tests for this.
void DestroyChannelOnIOThread(ChannelInfo* channel_info) {
  DCHECK(channel_info);
  DCHECK(channel_info->channel_id);
  DCHECK(internal::g_ipc_support);

  system::ChannelManager* channel_manager =
      internal::g_ipc_support->channel_manager();
  channel_manager->ShutdownChannelOnIOThread(channel_info->channel_id);
  delete channel_info;
}

// TODO(vtl): Write tests for this.
void DestroyChannel(ChannelInfo* channel_info,
                    std::function<void()>&& did_destroy_channel_callback,
                    RefPtr<TaskRunner>&& did_destroy_channel_runner) {
  DCHECK(channel_info);
  DCHECK(channel_info->channel_id);
  DCHECK(did_destroy_channel_callback);
  DCHECK(internal::g_ipc_support);

  system::ChannelManager* channel_manager =
      internal::g_ipc_support->channel_manager();
  channel_manager->ShutdownChannel(channel_info->channel_id,
                                   std::move(did_destroy_channel_callback),
                                   std::move(did_destroy_channel_runner));
  delete channel_info;
}

void WillDestroyChannelSoon(ChannelInfo* channel_info) {
  DCHECK(channel_info);
  DCHECK(internal::g_ipc_support);

  system::ChannelManager* channel_manager =
      internal::g_ipc_support->channel_manager();
  channel_manager->WillShutdownChannel(channel_info->channel_id);
}

}  // namespace embedder
}  // namespace mojo
