// Copyright 2013 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_CHANNEL_H_
#define MOJO_EDK_SYSTEM_CHANNEL_H_

#include <stdint.h>

#include <memory>
#include <unordered_map>

#include "mojo/edk/platform/scoped_platform_handle.h"
#include "mojo/edk/platform/task_runner.h"
#include "mojo/edk/system/channel_endpoint.h"
#include "mojo/edk/system/channel_endpoint_id.h"
#include "mojo/edk/system/incoming_endpoint.h"
#include "mojo/edk/system/message_in_transit.h"
#include "mojo/edk/system/raw_channel.h"
#include "mojo/edk/util/mutex.h"
#include "mojo/edk/util/ref_counted.h"
#include "mojo/edk/util/ref_ptr.h"
#include "mojo/edk/util/thread_annotations.h"
#include "mojo/edk/util/thread_checker.h"
#include "mojo/public/cpp/system/macros.h"

namespace mojo {

namespace embedder {
class PlatformSupport;
}

namespace platform {
class PlatformHandleWatcher;
}

namespace system {

class ChannelEndpointClient;
class ChannelManager;
class MessageInTransitQueue;

// This class is mostly thread-safe. It may be created and destroyed on any
// thread. However, |Init()| must be called on an I/O thread before other
// methods are called. Before destruction, |Shutdown()| must be called on that
// same thread, after which other methods may not be called. Subject to these
// restrictions, its public methods are otherwise thread-safe. (Many private
// methods are restricted to the I/O thread.)
//
// Note the lock order (in order of allowable acquisition):
// |ChannelEndpointClient| (e.g., |MessagePipe|), |ChannelEndpoint|, |Channel|.
// Thus |Channel| may not call into |ChannelEndpoint| with |Channel|'s lock
// held.
class Channel final : public util::RefCountedThreadSafe<Channel>,
                      public RawChannel::Delegate {
 public:
  // Note: Use |util::MakeRefCounted<Channel>()|.

  // This must be called on an I/O thread before any other methods are called.
  // |io_task_runner| and |io_watcher| should be for this thread. |raw_channel|
  // should be uninitialized.
  void Init(util::RefPtr<platform::TaskRunner>&& io_task_runner,
            platform::PlatformHandleWatcher* io_watcher,
            std::unique_ptr<RawChannel> raw_channel) MOJO_NOT_THREAD_SAFE;

  // Sets the channel manager associated with this channel. This should be set
  // at most once and only called before |WillShutdownSoon()| (and
  // |Shutdown()|). (This is called by the channel manager when adding a
  // channel; this should not be called before the channel is managed by the
  // channel manager.)
  void SetChannelManager(ChannelManager* channel_manager);

  // This must be called on the creation thread before destruction (which can
  // happen on any thread).
  void Shutdown();

  // Signals that |Shutdown()| will be called soon (this may be called from any
  // thread, unlike |Shutdown()|). Warnings will be issued if, e.g., messages
  // are written after this is called; other warnings may be suppressed. (This
  // may be called multiple times, or not at all.)
  //
  // If set, the channel manager associated with this channel will be reset.
  void WillShutdownSoon();

  // Called to set (i.e., attach and run) the bootstrap (first) endpoint on the
  // channel. Both the local and remote IDs are the bootstrap ID (given by
  // |ChannelEndpointId::GetBootstrap()|).
  //
  // (Bootstrapping is symmetric: Both sides call this, which will establish the
  // first connection across a channel.)
  void SetBootstrapEndpoint(util::RefPtr<ChannelEndpoint>&& endpoint);

  // Like |SetBootstrapEndpoint()|, but with explicitly-specified local and
  // remote IDs.
  //
  // (Bootstrapping is still symmetric, though the sides should obviously
  // interchange local and remote IDs. This can be used to allow multiple
  // "bootstrap" endpoints, though this is really most useful for testing.)
  void SetBootstrapEndpointWithIds(util::RefPtr<ChannelEndpoint>&& endpoint,
                                   ChannelEndpointId local_id,
                                   ChannelEndpointId remote_id);

  // This forwards |message| verbatim to |raw_channel_|.
  bool WriteMessage(std::unique_ptr<MessageInTransit> message);

  // See |RawChannel::IsWriteBufferEmpty()|.
  // TODO(vtl): Maybe we shouldn't expose this, and instead have a
  // |FlushWriteBufferAndShutdown()| or something like that.
  bool IsWriteBufferEmpty();

  // Removes the given endpoint from this channel (|local_id| and |remote_id|
  // are specified as an optimization; the latter should be an invalid
  // |ChannelEndpointId| if the endpoint is not yet running). Note: If this is
  // called, the |Channel| will *not* call
  // |ChannelEndpoint::DetachFromChannel()|.
  void DetachEndpoint(ChannelEndpoint* endpoint,
                      ChannelEndpointId local_id,
                      ChannelEndpointId remote_id);

  // Returns the size of a serialized endpoint (see |SerializeEndpoint...()| and
  // |DeserializeEndpoint()| below). This value will remain constant for a given
  // instance of |Channel|.
  size_t GetSerializedEndpointSize() const;

  // Endpoint serialization methods: From the |Channel|'s point of view, there
  // are three cases (discussed further below) and thus three methods.
  //
  // All three methods have a |destination| argument, which should be a buffer
  // to which auxiliary information will be written and which should be
  // transmitted to the peer |Channel| by some other means, but using this
  // |Channel|. It should be a buffer of (at least) the size returned by
  // |GetSerializedEndpointSize()| (exactly that much data will be written).
  //
  // All three also have a |message_queue| argument, which if non-null is the
  // queue of messages already received by the endpoint to be serialized.
  //
  // Note that "serialize" really means "send" -- the |endpoint| will be sent
  // "immediately". The contents of the |destination| buffer can then be used to
  // claim the rematerialized endpoint from the peer |Channel|. (|destination|
  // must be sent using this |Channel|, since otherwise it may be received
  // before it is valid to the peer |Channel|.)
  //
  // Case 1: The endpoint's peer is already closed.
  //
  // Case 2: The endpoint's peer is local (i.e., it has a
  // |ChannelEndpointClient| but no peer |ChannelEndpoint|).
  //
  // Case 3: The endpoint's peer is remote (i.e., it has a peer
  // |ChannelEndpoint|). (This has two subcases: the peer endpoint may be on
  // this |Channel| or another |Channel|.)
  void SerializeEndpointWithClosedPeer(void* destination,
                                       MessageInTransitQueue* message_queue);
  // This one returns the |ChannelEndpoint| for the serialized endpoint (which
  // can be used by, e.g., a |ProxyMessagePipeEndpoint|.
  util::RefPtr<ChannelEndpoint> SerializeEndpointWithLocalPeer(
      void* destination,
      MessageInTransitQueue* message_queue,
      util::RefPtr<ChannelEndpointClient>&& endpoint_client,
      unsigned endpoint_client_port);
  void SerializeEndpointWithRemotePeer(
      void* destination,
      MessageInTransitQueue* message_queue,
      util::RefPtr<ChannelEndpoint>&& peer_endpoint);

  // Deserializes an endpoint that was sent from the peer |Channel| (using
  // |SerializeEndpoint...()|. |source| should be (a copy of) the data that
  // |SerializeEndpoint...()| wrote, and must be (at least)
  // |GetSerializedEndpointSize()| bytes. This returns the deserialized
  // |IncomingEndpoint| (which can be converted into a |MessagePipe|) or null on
  // error.
  util::RefPtr<IncomingEndpoint> DeserializeEndpoint(const void* source);

  // See |RawChannel::GetSerializedPlatformHandleSize()|.
  size_t GetSerializedPlatformHandleSize() const;

  embedder::PlatformSupport* platform_support() const {
    return platform_support_;
  }

 private:
  FRIEND_REF_COUNTED_THREAD_SAFE(Channel);
  FRIEND_MAKE_REF_COUNTED(Channel);

  // |platform_support| must remain alive until after |Shutdown()| is called.
  explicit Channel(embedder::PlatformSupport* platform_support);
  ~Channel() override;

  // Helper for |DetachEndpoint()| (returns true if a "remove" should be sent).
  bool DetachEndpointInternal(ChannelEndpoint* endpoint,
                              ChannelEndpointId local_id,
                              ChannelEndpointId remote_id);

  // |RawChannel::Delegate| implementation (only called on the creation thread):
  void OnReadMessage(
      const MessageInTransit::View& message_view,
      std::unique_ptr<std::vector<platform::ScopedPlatformHandle>>
          platform_handles) override;
  void OnError(Error error) override;

  // Helpers for |OnReadMessage| (only called on the creation thread):
  void OnReadMessageForEndpoint(
      const MessageInTransit::View& message_view,
      std::unique_ptr<std::vector<platform::ScopedPlatformHandle>>
          platform_handles);
  void OnReadMessageForChannel(
      const MessageInTransit::View& message_view,
      std::unique_ptr<std::vector<platform::ScopedPlatformHandle>>
          platform_handles);

  // Handles "attach and run endpoint" messages.
  bool OnAttachAndRunEndpoint(ChannelEndpointId local_id,
                              ChannelEndpointId remote_id);
  // Handles "remove endpoint" messages.
  bool OnRemoveEndpoint(ChannelEndpointId local_id,
                        ChannelEndpointId remote_id);
  // Handles "remove endpoint ack" messages.
  bool OnRemoveEndpointAck(ChannelEndpointId local_id);

  // Handles errors (e.g., invalid messages) from the remote side. Callable from
  // any thread.
  void HandleRemoteError(const char* error_message);
  // Handles internal errors/failures from the local side. Callable from any
  // thread.
  void HandleLocalError(const char* error_message);

  // Helper for |SerializeEndpoint...()|: Attaches the given (non-bootstrap)
  // endpoint to this channel and runs it. This assigns the endpoint both local
  // and remote IDs. This will also send a
  // |Subtype::CHANNEL_ATTACH_AND_RUN_ENDPOINT| message to the remote side to
  // tell it to create an endpoint as well. This returns the *remote* ID (one
  // for which |is_remote()| returns true).
  //
  // TODO(vtl): Maybe limit the number of attached message pipes.
  ChannelEndpointId AttachAndRunEndpoint(
      util::RefPtr<ChannelEndpoint>&& endpoint);

  // Helper to send channel control messages. Returns true on success. Callable
  // from any thread.
  bool SendControlMessage(MessageInTransit::Subtype subtype,
                          ChannelEndpointId source_id,
                          ChannelEndpointId destination_id,
                          uint32_t num_bytes,
                          const void* bytes) MOJO_LOCKS_EXCLUDED(mutex_);

#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)
  util::ThreadChecker thread_checker_;
#endif  // !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON)

  embedder::PlatformSupport* const platform_support_;

  // Note: |ChannelEndpointClient|s (in particular, |MessagePipe|s) MUST NOT be
  // used under |mutex_|. E.g., |mutex_| can only be acquired after
  // |MessagePipe::lock_|, never before. Thus to call into a
  // |ChannelEndpointClient|, a reference should be acquired from
  // |local_id_to_endpoint_map_| under |mutex_| and then the lock released.
  // TODO(vtl): Annotate the above rule using |MOJO_ACQUIRED_{BEFORE,AFTER}()|,
  // once clang actually checks such annotations.
  // https://github.com/domokit/mojo/issues/313
  mutable util::Mutex mutex_;

  std::unique_ptr<RawChannel> raw_channel_ MOJO_GUARDED_BY(mutex_);
  bool is_running_ MOJO_GUARDED_BY(mutex_);
  // Set when |WillShutdownSoon()| is called.
  bool is_shutting_down_ MOJO_GUARDED_BY(mutex_);

  // Has a reference to us.
  ChannelManager* channel_manager_ MOJO_GUARDED_BY(mutex_);

  using IdToEndpointMap =
      std::unordered_map<ChannelEndpointId, util::RefPtr<ChannelEndpoint>>;
  // Map from local IDs to endpoints. If the endpoint is null, this means that
  // we're just waiting for the remove ack before removing the entry.
  IdToEndpointMap local_id_to_endpoint_map_ MOJO_GUARDED_BY(mutex_);
  // Note: The IDs generated by this should be checked for existence before use.
  LocalChannelEndpointIdGenerator local_id_generator_ MOJO_GUARDED_BY(mutex_);

  using IdToIncomingEndpointMap =
      std::unordered_map<ChannelEndpointId, util::RefPtr<IncomingEndpoint>>;
  // Map from local IDs to incoming endpoints (i.e., those received inside other
  // messages, but not yet claimed via |DeserializeEndpoint()|).
  IdToIncomingEndpointMap incoming_endpoints_ MOJO_GUARDED_BY(mutex_);
  // TODO(vtl): We need to keep track of remote IDs (so that we don't collide
  // if/when we wrap).
  RemoteChannelEndpointIdGenerator remote_id_generator_ MOJO_GUARDED_BY(mutex_);

  MOJO_DISALLOW_COPY_AND_ASSIGN(Channel);
};

}  // namespace system
}  // namespace mojo

#endif  // MOJO_EDK_SYSTEM_CHANNEL_H_
