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

#ifndef MOJO_EDK_SYSTEM_IPC_SUPPORT_H_
#define MOJO_EDK_SYSTEM_IPC_SUPPORT_H_

#include <memory>

#include "base/callback_forward.h"
#include "base/gtest_prod_util.h"
#include "mojo/edk/embedder/platform_task_runner.h"
#include "mojo/edk/embedder/process_type.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
#include "mojo/edk/embedder/slave_info.h"
#include "mojo/edk/system/channel_id.h"
#include "mojo/edk/system/connection_identifier.h"
#include "mojo/edk/system/process_identifier.h"
#include "mojo/edk/util/ref_ptr.h"
#include "mojo/public/cpp/system/macros.h"

namespace mojo {

namespace embedder {
class PlatformSupport;
class ProcessDelegate;
}

namespace system {

class ChannelManager;
class ConnectionManager;
class MessagePipeDispatcher;

// This test (and its helper function) need to be friended.
FORWARD_DECLARE_TEST(IPCSupportTest, MasterSlaveInternal);
FORWARD_DECLARE_TEST(IPCSupportTest, MultiprocessMasterSlaveInternal);
void MultiprocessMasterSlaveInternalTestChildTest();

// |IPCSupport| encapsulates all the objects that are needed to support IPC for
// a single "process" (whether that be a master or a slave).
//
// ("Process" typically means a real process, but for testing purposes, multiple
// instances can coexist within a single real process.)
//
// Each "process" must have an |embedder::PlatformSupport| and a suitable
// |embedder::ProcessDelegate|, together with an I/O thread and a thread on
// which to call delegate methods (which may be the same as the I/O thread).
//
// For testing purposes within a single real process, except for the I/O thread,
// these may be shared between "processes" (i.e., instances of |IPCSupport|) --
// there must be a separate I/O thread for each |IPCSupport|.
//
// Except for |ShutdownOnIOThread()|, this class is thread-safe. (No methods may
// be called during/after |ShutdownOnIOThread()|.)
class IPCSupport {
 public:
  // Constructor: initializes for the given |process_type|; |process_delegate|
  // must match the process type. |platform_handle| is only used for slave
  // processes.
  //
  // All the (pointer) arguments must remain alive (and, in the case of task
  // runners, continue to process tasks) until |ShutdownOnIOThread()| has been
  // called.
  IPCSupport(
      embedder::PlatformSupport* platform_support,
      embedder::ProcessType process_type,
      util::RefPtr<embedder::PlatformTaskRunner>&& delegate_thread_task_runner,
      embedder::ProcessDelegate* process_delegate,
      util::RefPtr<embedder::PlatformTaskRunner>&& io_thread_task_runner,
      embedder::ScopedPlatformHandle platform_handle);
  // Note: This object must be shut down before destruction (see
  // |ShutdownOnIOThread()|).
  ~IPCSupport();

  // This must be called (exactly once) on the I/O thread before this object is
  // destroyed (which may happen on any thread). Note: This does *not* call the
  // process delegate's |OnShutdownComplete()|.
  void ShutdownOnIOThread();

  // Generates a new (unique) connection identifier, for use with
  // |ConnectToSlave()| and |ConnectToMaster()|, below.
  ConnectionIdentifier GenerateConnectionIdentifier();

  // Called in the master process to connect a slave process to the IPC system.
  //
  // |connection_id| should be a unique connection identifier, which will also
  // be given to the slave (in |ConnectToMaster()|, below). |slave_info| is
  // context for the caller (it is treated as an opaque value by this class).
  // |platform_handle| should be the master's handle to an OS "pipe" between
  // master and slave. This will then bootstrap a |Channel| between master and
  // slave together with an initial message pipe (returning a dispatcher for the
  // master's side).
  //
  // |callback| will be run after the |Channel| is created, either using
  // |callback_thread_task_runner| (if it is non-null) or on the I/O thread.
  // |*channel_id| will be set to the ID for the channel (immediately); the
  // channel may be destroyed using this ID, but only after the callback has
  // been run.
  //
  // TODO(vtl): Add some more channel management functionality to this class.
  // Maybe make this callback interface more sane.
  util::RefPtr<MessagePipeDispatcher> ConnectToSlave(
      const ConnectionIdentifier& connection_id,
      embedder::SlaveInfo slave_info,
      embedder::ScopedPlatformHandle platform_handle,
      const base::Closure& callback,
      util::RefPtr<embedder::PlatformTaskRunner>&& callback_thread_task_runner,
      ChannelId* channel_id);

  // Called in a slave process to connect it to the master process and thus the
  // IPC system, creating a |Channel| and an initial message pipe (return a
  // dispatcher for the slave's side). See |ConnectToSlave()|, above.
  //
  // |callback|, |callback_thread_task_runner|, and |channel_id| are as in
  // |ConnectToSlave()|.
  //
  // TODO(vtl): |ConnectToSlave()|'s channel management TODO also applies here.
  util::RefPtr<MessagePipeDispatcher> ConnectToMaster(
      const ConnectionIdentifier& connection_id,
      const base::Closure& callback,
      util::RefPtr<embedder::PlatformTaskRunner>&& callback_thread_task_runner,
      ChannelId* channel_id);

  embedder::ProcessType process_type() const { return process_type_; }
  embedder::ProcessDelegate* process_delegate() const {
    return process_delegate_;
  }
  embedder::PlatformTaskRunner* delegate_thread_task_runner() const {
    return delegate_thread_task_runner_.get();
  }
  embedder::PlatformTaskRunner* io_thread_task_runner() const {
    return io_thread_task_runner_.get();
  }
  // TODO(vtl): The things that use the following should probably be moved into
  // this class.
  ChannelManager* channel_manager() const { return channel_manager_.get(); }

 private:
  // These test |ConnectToSlaveInternal()| and |ConnectToMasterInternal()|.
  FRIEND_TEST_ALL_PREFIXES(IPCSupportTest, MasterSlaveInternal);
  FRIEND_TEST_ALL_PREFIXES(IPCSupportTest, MultiprocessMasterSlaveInternal);
  friend void MultiprocessMasterSlaveInternalTestChildTest();

  // Helper for |ConnectToSlave()|. Connects (using the connection manager) to
  // the slave using |platform_handle| (a handle to an OS "pipe" between master
  // and slave) and creates a second OS "pipe" between the master and slave
  // (returning the master's handle). |*slave_process_identifier| will be set to
  // the process identifier assigned to the slave.
  embedder::ScopedPlatformHandle ConnectToSlaveInternal(
      const ConnectionIdentifier& connection_id,
      embedder::SlaveInfo slave_info,
      embedder::ScopedPlatformHandle platform_handle,
      ProcessIdentifier* slave_process_identifier);

  // Helper for |ConnectToMaster()|. Connects (using the connection manager) to
  // the master (using the handle to the OS "pipe" that was given to
  // |SlaveConnectionManager::Init()|) and creates a second OS "pipe" between
  // the master and slave (returning the slave's handle).
  embedder::ScopedPlatformHandle ConnectToMasterInternal(
      const ConnectionIdentifier& connection_id);

  ConnectionManager* connection_manager() const {
    return connection_manager_.get();
  }

  // These are all set on construction and reset by |ShutdownOnIOThread()|.
  embedder::ProcessType process_type_;
  util::RefPtr<embedder::PlatformTaskRunner> delegate_thread_task_runner_;
  embedder::ProcessDelegate* process_delegate_;
  util::RefPtr<embedder::PlatformTaskRunner> io_thread_task_runner_;

  std::unique_ptr<ConnectionManager> connection_manager_;
  std::unique_ptr<ChannelManager> channel_manager_;

  MOJO_DISALLOW_COPY_AND_ASSIGN(IPCSupport);
};

}  // namespace system
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_IPC_SUPPORT_H_
