// Copyright (c) 2012 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 BASE_MACH_IPC_MAC_H_
#define BASE_MACH_IPC_MAC_H_

#include <mach/mach.h>
#include <mach/message.h>
#include <servers/bootstrap.h>
#include <sys/types.h>

#include <CoreServices/CoreServices.h>

#include "base/base_export.h"
#include "base/basictypes.h"

//==============================================================================
// DISCUSSION:
//
// The three main classes of interest are
//
//  MachMessage:    a wrapper for a Mach message of the following form
//   mach_msg_header_t
//   mach_msg_body_t
//   optional descriptors
//   optional extra message data
//
//  MachReceiveMessage and MachSendMessage subclass MachMessage
//    and are used instead of MachMessage which is an abstract base class
//
//  ReceivePort:
//    Represents a Mach port for which we have receive rights
//
//  MachPortSender:
//    Represents a Mach port for which we have send rights
//
// Here's an example to receive a message on a server port:
//
//        // This creates our named server port
//        ReceivePort receivePort("com.Google.MyService");
//
//        MachReceiveMessage message;
//        kern_return_t result = receivePort.WaitForMessage(&message, 0);
//
//        if (result == KERN_SUCCESS && message.GetMessageID() == 57) {
//          mach_port_t task = message.GetTranslatedPort(0);
//          mach_port_t thread = message.GetTranslatedPort(1);
//
//          char *messageString = message.GetData();
//
//          printf("message string = %s\n", messageString);
//        }
//
// Here is an example of using these classes to send a message to this port:
//
//    // send to already named port
//    MachPortSender sender("com.Google.MyService");
//    MachSendMessage message(57);      // our message ID is 57
//
//    // add some ports to be translated for us
//    message.AddDescriptor(mach_task_self());     // our task
//    message.AddDescriptor(mach_thread_self());   // this thread
//
//    char messageString[] = "Hello server!\n";
//    message.SetData(messageString, strlen(messageString)+1);
//    // timeout 1000ms
//    kern_return_t result = sender.SendMessage(message, 1000);
//

#define PRINT_MACH_RESULT(result_, message_) \
  printf(message_" %s (%d)\n", mach_error_string(result_), result_ );

namespace base {

//==============================================================================
// A wrapper class for mach_msg_port_descriptor_t (with same memory layout)
// with convenient constructors and accessors
class MachMsgPortDescriptor : public mach_msg_port_descriptor_t {
 public:
  // General-purpose constructor
  MachMsgPortDescriptor(mach_port_t in_name,
                        mach_msg_type_name_t in_disposition) {
    name = in_name;
    pad1 = 0;
    pad2 = 0;
    disposition = in_disposition;
    type = MACH_MSG_PORT_DESCRIPTOR;
  }

  // For passing send rights to a port
  MachMsgPortDescriptor(mach_port_t in_name) {
    name = in_name;
    pad1 = 0;
    pad2 = 0;
    disposition = MACH_MSG_TYPE_PORT_SEND;
    type = MACH_MSG_PORT_DESCRIPTOR;
  }

  // Copy constructor
  MachMsgPortDescriptor(const MachMsgPortDescriptor& desc) {
    name = desc.name;
    pad1 = desc.pad1;
    pad2 = desc.pad2;
    disposition = desc.disposition;
    type = desc.type;
  }

  mach_port_t GetMachPort() const {
    return name;
  }

  mach_msg_type_name_t GetDisposition() const {
    return disposition;
  }

  // For convenience
  operator mach_port_t() const {
    return GetMachPort();
  }
};

//==============================================================================
// MachMessage: a wrapper for a Mach message
//  (mach_msg_header_t, mach_msg_body_t, extra data)
//
//  This considerably simplifies the construction of a message for sending
//  and the getting at relevant data and descriptors for the receiver.
//
//  This class can be initialized using external storage of an arbitrary size
//  or it can manage storage internally.
//  1. If storage is allocated internally, the combined size of the descriptors
//  plus data must be less than 1024.  But as a benefit no memory allocation is
//  necessary.
//  2. For external storage, a buffer of at least EmptyMessageSize() must be
//  provided.
//
//  A MachMessage object is used by ReceivePort::WaitForMessage
//  and MachPortSender::SendMessage
//
class BASE_EXPORT MachMessage {
 public:
  static const size_t kEmptyMessageSize;

  virtual ~MachMessage();

  // The receiver of the message can retrieve the raw data this way
  u_int8_t *GetData() {
    return GetDataLength() > 0 ? GetDataPacket()->data : NULL;
  }

  u_int32_t GetDataLength() {
    return EndianU32_LtoN(GetDataPacket()->data_length);
  }

  // The message ID may be used as a code identifying the type of message
  void SetMessageID(int32_t message_id) {
    GetDataPacket()->id = EndianU32_NtoL(message_id);
  }

  int32_t GetMessageID() { return EndianU32_LtoN(GetDataPacket()->id); }

  // Adds a descriptor (typically a Mach port) to be translated
  // returns true if successful, otherwise not enough space
  bool AddDescriptor(const MachMsgPortDescriptor &desc);

  int GetDescriptorCount() const {
    return storage_->body.msgh_descriptor_count;
  }

  MachMsgPortDescriptor *GetDescriptor(int n);

  // Convenience method which gets the Mach port described by the descriptor
  mach_port_t GetTranslatedPort(int n);

  // A simple message is one with no descriptors
  bool IsSimpleMessage() const { return GetDescriptorCount() == 0; }

  // Sets raw data for the message (returns false if not enough space)
  bool SetData(const void* data, int32_t data_length);

 protected:
  // Consider this an abstract base class - must create an actual instance
  // of MachReceiveMessage or MachSendMessage
  MachMessage();

  // Constructor for use with preallocate storage.
  // storage_length must be >= EmptyMessageSize()
  MachMessage(void *storage, size_t storage_length);

  friend class ReceivePort;
  friend class MachPortSender;

  // Represents raw data in our message
  struct MessageDataPacket {
    int32_t  id;          // little-endian
    int32_t  data_length; // little-endian
    u_int8_t data[1];     // actual size limited by storage_length_bytes_
  };

  MessageDataPacket* GetDataPacket();

  void SetDescriptorCount(int n);
  void SetDescriptor(int n, const MachMsgPortDescriptor &desc);

  // Returns total message size setting msgh_size in the header to this value
  int CalculateSize();

  // Returns total storage size that this object can grow to, this is inclusive
  // of the Mach header.
  size_t MaxSize() const { return storage_length_bytes_; }

  mach_msg_header_t *Head() { return &(storage_->head); }

 private:
  struct MachMessageData {
    mach_msg_header_t  head;
    mach_msg_body_t    body;
    // descriptors and data may be embedded here.
    u_int8_t           padding[1024];
  };

  MachMessageData *storage_;
  size_t storage_length_bytes_;
  bool own_storage_;  // Is storage owned by this object?
};

//==============================================================================
// MachReceiveMessage and MachSendMessage are useful to separate the idea
// of a Mach message being sent and being received, and adds increased type
// safety:
//  ReceivePort::WaitForMessage() only accepts a MachReceiveMessage
//  MachPortSender::SendMessage() only accepts a MachSendMessage

//==============================================================================
class MachReceiveMessage : public MachMessage {
 public:
  MachReceiveMessage() : MachMessage() {}
  MachReceiveMessage(void *storage, size_t storage_length)
      : MachMessage(storage, storage_length) {}

 private:
    DISALLOW_COPY_AND_ASSIGN(MachReceiveMessage);
};

//==============================================================================
class BASE_EXPORT MachSendMessage : public MachMessage {
 public:
  explicit MachSendMessage(int32_t message_id);
  MachSendMessage(void *storage, size_t storage_length, int32_t message_id);

 private:
  void Initialize(int32_t message_id);

  DISALLOW_COPY_AND_ASSIGN(MachSendMessage);
};

//==============================================================================
// Represents a Mach port for which we have receive rights
class BASE_EXPORT ReceivePort {
 public:
  // Creates a new Mach port for receiving messages and registers a name for it
  explicit ReceivePort(const char *receive_port_name);

  // Given an already existing Mach port, use it.  We take ownership of the
  // port and deallocate it in our destructor.
  explicit ReceivePort(mach_port_t receive_port);

  // Create a new Mach port for receiving messages
  ReceivePort();

  ~ReceivePort();

  // Waits on the Mach port until message received or timeout.  If |timeout| is
  // MACH_MSG_TIMEOUT_NONE, this method waits forever.
  kern_return_t WaitForMessage(MachReceiveMessage *out_message,
                               mach_msg_timeout_t timeout);

  // The underlying Mach port that we wrap
  mach_port_t  GetPort() const { return port_; }

 private:
  mach_port_t   port_;
  kern_return_t init_result_;

  DISALLOW_COPY_AND_ASSIGN(ReceivePort);
};

//==============================================================================
// Represents a Mach port for which we have send rights
class BASE_EXPORT MachPortSender {
 public:
  // get a port with send rights corresponding to a named registered service
  explicit MachPortSender(const char *receive_port_name);


  // Given an already existing Mach port, use it. Does not take ownership of
  // |send_port|.
  explicit MachPortSender(mach_port_t send_port);

  kern_return_t SendMessage(MachSendMessage &message,
                            mach_msg_timeout_t timeout);

 private:
  mach_port_t   send_port_;
  kern_return_t init_result_;

  DISALLOW_COPY_AND_ASSIGN(MachPortSender);
};

//==============================================================================
// Static utility functions.

namespace mac {

// Returns the number of Mach ports to which the given task has a right.
// Note that unless the calling task has send rights to the passed task port,
// this will fail unless the calling task is running as root.
kern_return_t BASE_EXPORT GetNumberOfMachPorts(mach_port_t task_port,
                                               int* port_count);

}  // namespace mac

}  // namespace base

#endif // BASE_MACH_IPC_MAC_H_
