// Copyright 2018 The Fuchsia 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 LIB_FIDL_CPP_MESSAGE_H_
#define LIB_FIDL_CPP_MESSAGE_H_

#include <lib/fidl/coding.h>
#include <lib/fidl/cpp/message_part.h>
#include <lib/fidl/cpp/wire_format_metadata.h>
#include <lib/fidl/internal.h>
#include <lib/fidl/txn_header.h>
#include <zircon/fidl.h>

#include <vector>

namespace fidl {

class HLCPPIncomingMessage;
class HLCPPOutgoingMessage;

// An incoming FIDL transactional message body.
//
// A FIDL transactional message body has two parts: the |bytes| and the |handles|. The |bytes|
// represent only the transactional message's body, and may be a view into a larger buffer that
// is prepended by the transactional message's header bytes as well.
//
// A HLCPPIncomingBody object does not own the storage for the message parts.
class HLCPPIncomingBody {
  // If an |HLCPPIncomingBody| is held by an |HLCPPIncomingMessage| (or, when used as a response to
  // a Call, by an |HLCPPOutgoingMessage|), it is important that the |BytePart|s of the two
  // containers are kept in sync: the |BytePart| of the |HLCPPIncomingMessage| should always contain
  // a pointer 16 bytes before the pointer contained by the |HLCPPIncomingBody| it owns, and the
  // |actual()| size of the former should be 16 bytes larger than the latter. By declaring these two
  // potential owners friends, we allow them resize/modify this inner container whenever the outer
  // one changes, while preventing users of |HLCPPIncomingBody| in the standalone case from directly
  // modifying its innards.
  friend class HLCPPIncomingMessage;
  friend class HLCPPOutgoingMessage;

 public:
  // Creates a message body without any storage.
  HLCPPIncomingBody();

  HLCPPIncomingBody(BytePart bytes, HandleInfoPart handles);

  ~HLCPPIncomingBody();

  HLCPPIncomingBody(const HLCPPIncomingBody& other) = delete;
  HLCPPIncomingBody& operator=(const HLCPPIncomingBody& other) = delete;

  HLCPPIncomingBody(HLCPPIncomingBody&& other);
  HLCPPIncomingBody& operator=(HLCPPIncomingBody&& other);

  // The storage for the bytes of the message body.
  const BytePart& bytes() const { return bytes_; }

  // The storage for the handles of the message body.
  //
  // When the message is encoded, the handle values are stored in this part of
  // the message. When the message is decoded, this part of the message is
  // empty and the handle values are stored in the bytes().
  HandleInfoPart& handles() { return handles_; }
  const HandleInfoPart& handles() const { return handles_; }

  // The message body bytes interpreted as the given type.
  template <typename T>
  T* GetBytesAs() const {
    return reinterpret_cast<T*>(bytes_.data());
  }

  // Decodes the transactional message body in-place.
  //
  // |metadata| describes features/revision information about the wire format.
  zx_status_t Decode(const WireFormatMetadata& metadata, const fidl_type_t* type,
                     const char** error_msg_out);

  // Stop tracking the handles in stored in handles(), without closing them.
  //
  // Typically, these handles will be extracted during decode or the
  // message's destructor, so this function will be unnecessary. However,
  // for clients of ulib/fidl which decode message manually, this function
  // is necessary to prevent extracted handles from being closed.
  void ClearHandlesUnsafe();

 private:
  BytePart bytes_;
  HandleInfoPart handles_;

  // Because |HLCPPIncomingBody| does not own its storage, these methods are only accessible to
  // friend classes that are using |HLCPPIncomingBody| as a view.
  void set_bytes(BytePart bytes) { bytes_ = static_cast<BytePart&&>(bytes); }
  void resize_bytes(uint32_t num_bytes) { bytes_.set_actual(num_bytes); }
};

// An incoming FIDL transactional message.
//
// A FIDL transactional message has two parts: the |bytes| and the |handles|. The |bytes| are
// divided into a header (of type fidl_message_header_t) and a body, which follows the header.
//
// A HLCPPIncomingMessage object does not own the storage for the message parts.
class HLCPPIncomingMessage {
 public:
  // Creates a message without any storage.
  HLCPPIncomingMessage();

  // Creates a message whose storage is backed by |bytes| and |handles|.
  //
  // The constructed |Message| object does not take ownership of the given
  // storage, although does take ownership of zircon handles contained withing
  // handles.
  HLCPPIncomingMessage(BytePart bytes, HandleInfoPart handles);

  HLCPPIncomingMessage(const HLCPPIncomingMessage& other) = delete;
  HLCPPIncomingMessage& operator=(const HLCPPIncomingMessage& other) = delete;

  HLCPPIncomingMessage(HLCPPIncomingMessage&& other);
  HLCPPIncomingMessage& operator=(HLCPPIncomingMessage&& other);

  // The header at the start of the message.
  const fidl_message_header_t& header() const {
    return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
  }
  fidl_message_header_t& header() {
    return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
  }

  // The transaction ID in the message header.
  zx_txid_t txid() const { return header().txid; }
  void set_txid(zx_txid_t txid) { header().txid = txid; }

  // The ordinal in the message header.
  uint64_t ordinal() const { return header().ordinal; }

  // Whether this message is in a supported version of the wire format.
  bool is_supported_version() const { return fidl_validate_txn_header(&header()) == ZX_OK; }

  // Returns true if this message is requesting the message be treated as a flexible method.
  bool is_flexible() const {
    return (header().dynamic_flags & FIDL_MESSAGE_HEADER_DYNAMIC_FLAGS_FLEXIBLE_METHOD) != 0;
  }

  // The message body that follows the header.
  const HLCPPIncomingBody& body_view() const { return body_view_; }
  HLCPPIncomingBody& body_view() { return body_view_; }

  // Is this a message containing only a header?
  bool has_only_header() const { return bytes_.actual() == sizeof(fidl_message_header_t); }

  // The message payload that follows the header interpreted as the given type.
  template <typename T>
  T* GetBodyViewAs() const {
    return reinterpret_cast<T*>(body_view_.bytes().data());
  }

  // The storage for the bytes of the transactional message.
  const BytePart& bytes() const { return bytes_; }

  // The message bytes interpreted as the given type.
  template <typename T>
  T* GetBytesAs() const {
    return reinterpret_cast<T*>(bytes_.data());
  }

  void set_bytes(BytePart bytes) {
    bytes_ = static_cast<BytePart&&>(bytes);
    body_view_.set_bytes(BytePart(bytes_, sizeof(fidl_message_header_t)));
  }
  void resize_bytes(uint32_t num_bytes) {
    bytes_.set_actual(num_bytes);
    body_view_.resize_bytes(num_bytes - sizeof(fidl_message_header_t));
  }

  // The storage for the handles of the transactional message.
  //
  // When the message is encoded, the handle values are stored in this part of the message. When the
  // message is decoded, this part of the message is empty and the handle values are stored in the
  // |bytes()|.
  HandleInfoPart& handles() { return body_view_.handles(); }
  const HandleInfoPart& handles() const { return body_view_.handles(); }

  // Decodes the transactional message in-place.
  //
  // The transactional message must previously have been in an encoded state, for example, either by
  // being read from a zx_channel_t or having been encoded using the |Encode| method.
  zx_status_t Decode(const fidl_type_t* type, const char** error_msg_out);

  // Read a transactional message from the given channel.
  //
  // The bytes read from the channel are stored in |bytes()| and the handles read from the channel
  // are stored in |handles()|. Existing data in these buffers is overwritten.
  zx_status_t Read(zx_handle_t channel, uint32_t flags);

  // Stop tracking the handles in stored in handles(), without closing them.
  //
  // Typically, these handles will be extracted during decode or the
  // message's destructor, so this function will be unnecessary. However,
  // for clients of ulib/fidl which decode message manually, this function
  // is necessary to prevent extracted handles from being closed.
  void ClearHandlesUnsafe();

 private:
  BytePart bytes_;
  HLCPPIncomingBody body_view_;
};

// An outgoing FIDL transactional message body.
//
// A FIDL transactional message body has two parts: the |bytes| and the |handles|. The |bytes|
// represent only the transactional message's body, and may be a view into a larger buffer that
// is prepended by the transactional message's header bytes as well.
//
// A HLCPPOutgoingBody object does not own the storage for the message parts.
class HLCPPOutgoingBody {
  // If an |HLCPPOutgoingBody| is held by an |HLCPPOutgoingMessage| it is important that the
  // |BytePart|s of the two containers are kept in sync: the |BytePart| of the
  // |HLCPPOutgoingMessage| should always contain a pointer 16 bytes before the pointer contained by
  // the |HLCPPOutgoingBody| it owns, and the |actual()| size of the former should be 16 bytes
  // larger than the latter. By declaring these two potential owners friends, we allow them
  // resize/modify this inner container whenever the outer one changes, while preventing users of
  // |HLCPPOutgoingBody| in the standalone case from directly modifying its innards.
  friend class HLCPPOutgoingMessage;

 public:
  // Creates a message body without any storage.
  HLCPPOutgoingBody();

  HLCPPOutgoingBody(BytePart bytes, HandleDispositionPart handles);

  ~HLCPPOutgoingBody();

  HLCPPOutgoingBody(const HLCPPOutgoingBody& other) = delete;
  HLCPPOutgoingBody& operator=(const HLCPPOutgoingBody& other) = delete;

  HLCPPOutgoingBody(HLCPPOutgoingBody&& other);
  HLCPPOutgoingBody& operator=(HLCPPOutgoingBody&& other);

  // The storage for the bytes of the message body.
  const BytePart& bytes() const { return bytes_; }

  // The storage for the handles of the message body.
  //
  // When the message is encoded, the handle values are stored in this part of
  // the message. When the message is decoded, this part of the message is
  // empty and the handle values are stored in the bytes().
  HandleDispositionPart& handles() { return handles_; }
  const HandleDispositionPart& handles() const { return handles_; }

  // The message body bytes interpreted as the given type.
  template <typename T>
  T* GetBytesAs() const {
    return reinterpret_cast<T*>(bytes_.data());
  }

  // Validates the message body in-place.
  //
  // The message must already be in an encoded state, for example, either by
  // being read from a zx_channel_t or having been created in that state.
  //
  // Does not modify the message.
  zx_status_t Validate(const internal::WireFormatVersion& version, const fidl_type_t* type,
                       const char** error_msg_out) const;

  // Stop tracking the handles in stored in handles(), without closing them.
  //
  // Typically, these handles will be extracted during decode or the
  // message's destructor, so this function will be unnecessary. However,
  // for clients of ulib/fidl which decode message manually, this function
  // is necessary to prevent extracted handles from being closed.
  void ClearHandlesUnsafe();

 private:
  BytePart bytes_;
  HandleDispositionPart handles_;

  void set_bytes(BytePart bytes) { bytes_ = static_cast<BytePart&&>(bytes); }
  void resize_bytes(uint32_t num_bytes) { bytes_.set_actual(num_bytes); }
};

// An outgoing FIDL transactional message.
//
// A FIDL transactional message has two parts: the |bytes| and the |handles|. The |bytes| are
// divided into a header (of type fidl_message_header_t) and a body, which follows the header.
//
// A HLCPPOutgoingMessage object does not own the storage for the message parts.
class HLCPPOutgoingMessage {
 public:
  // Creates a message without any storage.
  HLCPPOutgoingMessage();

  // Creates a message whose storage is backed by |bytes| and |handles|.
  //
  // The constructed |Message| object does not take ownership of the given
  // storage, although does take ownership of zircon handles contained withing
  // handles.
  HLCPPOutgoingMessage(BytePart bytes, HandleDispositionPart handles);

  HLCPPOutgoingMessage(const HLCPPOutgoingMessage& other) = delete;
  HLCPPOutgoingMessage& operator=(const HLCPPOutgoingMessage& other) = delete;

  HLCPPOutgoingMessage(HLCPPOutgoingMessage&& other);
  HLCPPOutgoingMessage& operator=(HLCPPOutgoingMessage&& other);

  // The header at the start of the message.
  const fidl_message_header_t& header() const {
    return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
  }
  fidl_message_header_t& header() {
    return *reinterpret_cast<fidl_message_header_t*>(bytes_.data());
  }

  // The transaction ID in the message header.
  zx_txid_t txid() const { return header().txid; }
  void set_txid(zx_txid_t txid) { header().txid = txid; }

  // The ordinal in the message header.
  uint64_t ordinal() const { return header().ordinal; }

  // The message body that follows the header.
  const HLCPPOutgoingBody& body_view() const { return body_view_; }

  // Is this a message containing only a header?
  bool has_only_header() const { return bytes_.actual() == sizeof(fidl_message_header_t); }

  // The storage for the bytes of the transactional message.
  const BytePart& bytes() const { return bytes_; }

  void set_bytes(BytePart bytes) {
    bytes_ = static_cast<BytePart&&>(bytes);
    body_view_.set_bytes(BytePart(bytes_, sizeof(fidl_message_header_t)));
  }
  void resize_bytes(uint32_t num_bytes) {
    bytes_.set_actual(num_bytes);
    body_view_.resize_bytes(num_bytes - sizeof(fidl_message_header_t));
  }

  // The storage for the handles of the message.
  //
  // When the message is encoded, the handle values are stored in this part of
  // the message. When the message is decoded, this part of the message is
  // empty and the handle values are stored in the bytes().
  HandleDispositionPart& handles() { return body_view_.handles(); }
  const HandleDispositionPart& handles() const { return body_view_.handles(); }

  // Validates the transactional message body in-place.
  //
  // The message must already be in an encoded state, for example, either by
  // being read from a zx_channel_t or having been created in that state.
  //
  // Does not modify the message.
  zx_status_t Validate(const fidl_type_t* type, const char** error_msg_out) const;

  // Writes a transactional message to the given channel.
  //
  // The bytes stored in bytes() are written to the channel and the handles
  // stored in handles() are written to the channel.
  //
  // If this method returns ZX_OK, handles() will be empty because they were
  // consumed by this operation.
  zx_status_t Write(zx_handle_t channel, uint32_t flags);

  // Issues a synchronous send and receive transaction on the given channel.
  //
  // The bytes stored in bytes() are written to the channel and the handles
  // stored in handles() are written to the channel. The bytes read from the
  // channel are stored in response->bytes() and the handles read from the
  // channel are stored in response->handles().
  //
  // If this method returns ZX_OK, handles() will be empty because they were
  // consumed by this operation.
  zx_status_t Call(zx_handle_t channel, uint32_t flags, zx_time_t deadline,
                   HLCPPIncomingMessage* response);

  // Stop tracking the handles in stored in handles(), without closing them.
  //
  // Typically, these handles will be extracted during decode or the
  // message's destructor, so this function will be unnecessary. However,
  // for clients of ulib/fidl which decode message manually, this function
  // is necessary to prevent extracted handles from being closed.
  void ClearHandlesUnsafe();

 private:
  BytePart bytes_;
  HLCPPOutgoingBody body_view_;
};

}  // namespace fidl

#endif  // LIB_FIDL_CPP_MESSAGE_H_
