#ifndef ANDROID_PDX_SERVICE_H_
#define ANDROID_PDX_SERVICE_H_

#include <errno.h>
#include <log/log.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <memory>
#include <mutex>
#include <string>
#include <unordered_map>
#include <vector>

#include "pdx/channel_handle.h"
#include "pdx/file_handle.h"
#include "pdx/message_reader.h"
#include "pdx/message_writer.h"
#include "pdx/service_endpoint.h"

namespace android {
namespace pdx {

class Service;

namespace opcodes {

/*
 * Reserved message opcodes used by libpdx. The reserved opcodes start at the
 * max positive signed integer for the system and go down.
 * In contrast, service opcodes start at zero and go up. This scheme leaves
 * most of the positive integer space for services, a tiny fraction of the
 * positive integer space for the framework, and the entire negative integer
 * space for the kernel.
 */
#define PDX_OPCODE(name, n) name = ((-1U >> 1) - (n))  // 0x7fff..ffff - n

enum {
  // System message sent when a new client channel is open.
  CHANNEL_OPEN = -1,
  // System message sent when a channel is closed.
  CHANNEL_CLOSE = -2,
  // Request the service to reload system properties.
  PDX_OPCODE(REPORT_SYSPROP_CHANGE, 0),
  // Request the service to dump state and return it in a text buffer.
  PDX_OPCODE(DUMP_STATE, 1),
};

}  // namespace opcodes

/*
 * Base class of service-side per-channel context classes.
 */
class Channel : public std::enable_shared_from_this<Channel> {
 public:
  Channel() {}
  virtual ~Channel() {}

  /*
   * Utility to get a shared_ptr reference from the channel context pointer.
   */
  static std::shared_ptr<Channel> GetFromMessageInfo(const MessageInfo& info);
};

/*
 * Message class represents an RPC message, and implicitly the blocked sender
 * waiting for a response. Every message should get a reply, at some point
 * (unless the endpoint is closed), to prevent clients from blocking
 * indefinitely. In order to enforce this and prevent leaking message ids,
 * Message automatically replies with an error to the client on destruction,
 * unless one of two things happens:
 *
 *     1. The service calls one of the reply methods before the Message is
 *        destroyed.
 *     2. The responsibility for the message is moved to another instance of
 *        Message, using either move construction or move assignment.
 *
 * The second case is useful for services that need to delay responding to a
 * sender until a later time. In this situation the service can move the
 * Message to another instance in a suitable data structure for later use. The
 * moved-to Message then takes on the same behavior and responsibilities
 * described above.
 */
class Message : public OutputResourceMapper, public InputResourceMapper {
 public:
  Message();
  Message(const MessageInfo& info);
  ~Message();

  /*
   * Message objects support move construction and assignment.
   */
  Message(Message&& other);
  Message& operator=(Message&& other);

  /*
   * Read/write payload, in either single buffer or iovec form.
   */
  Status<size_t> ReadVector(const iovec* vector, size_t vector_length);
  Status<size_t> Read(void* buffer, size_t length);
  Status<size_t> WriteVector(const iovec* vector, size_t vector_length);
  Status<size_t> Write(const void* buffer, size_t length);

  template <size_t N>
  inline Status<size_t> ReadVector(const iovec (&vector)[N]) {
    return ReadVector(vector, N);
  }

  template <size_t N>
  inline Status<size_t> WriteVector(const iovec (&vector)[N]) {
    return WriteVector(vector, N);
  }

  // Helper functions to read/write all requested bytes, and return EIO if not
  // all were read/written.
  Status<void> ReadVectorAll(const iovec* vector, size_t vector_length);
  Status<void> WriteVectorAll(const iovec* vector, size_t vector_length);

  inline Status<void> ReadAll(void* buffer, size_t length) {
    Status<size_t> status = Read(buffer, length);
    if (status && status.get() < length)
      status.SetError(EIO);
    Status<void> ret;
    ret.PropagateError(status);
    return ret;
  }
  inline Status<void> WriteAll(const void* buffer, size_t length) {
    Status<size_t> status = Write(buffer, length);
    if (status && status.get() < length)
      status.SetError(EIO);
    Status<void> ret;
    ret.PropagateError(status);
    return ret;
  }

  template <size_t N>
  inline Status<void> ReadVectorAll(const iovec (&vector)[N]) {
    return ReadVectorAll(vector, N);
  }

  template <size_t N>
  inline Status<void> WriteVectorAll(const iovec (&vector)[N]) {
    return WriteVectorAll(vector, N);
  }

  // OutputResourceMapper
  Status<FileReference> PushFileHandle(const LocalHandle& handle) override;
  Status<FileReference> PushFileHandle(const BorrowedHandle& handle) override;
  Status<FileReference> PushFileHandle(const RemoteHandle& handle) override;
  Status<ChannelReference> PushChannelHandle(
      const LocalChannelHandle& handle) override;
  Status<ChannelReference> PushChannelHandle(
      const BorrowedChannelHandle& handle) override;
  Status<ChannelReference> PushChannelHandle(
      const RemoteChannelHandle& handle) override;

  // InputResourceMapper
  bool GetFileHandle(FileReference ref, LocalHandle* handle) override;
  bool GetChannelHandle(ChannelReference ref,
                        LocalChannelHandle* handle) override;

  /*
   * Various ways to reply to a message.
   */
  Status<void> Reply(int return_code);
  Status<void> ReplyError(unsigned int error);
  Status<void> ReplyFileDescriptor(unsigned int fd);
  Status<void> Reply(const LocalHandle& handle);
  Status<void> Reply(const BorrowedHandle& handle);
  Status<void> Reply(const RemoteHandle& handle);
  Status<void> Reply(const LocalChannelHandle& handle);
  Status<void> Reply(const BorrowedChannelHandle& handle);
  Status<void> Reply(const RemoteChannelHandle& handle);

  template <typename T>
  inline Status<void> Reply(const Status<T>& status) {
    return status ? Reply(status.get()) : ReplyError(status.error());
  }

  inline Status<void> Reply(const Status<void>& status) {
    return status ? Reply(0) : ReplyError(status.error());
  }

  /*
   * Update the channel event bits with the given clear and set masks.
   */
  Status<void> ModifyChannelEvents(int clear_mask, int set_mask);

  /*
   * Create a new channel and push it as a file descriptor to the client. See
   * Service::PushChannel() for a detail description of this method's operation.
   */
  Status<RemoteChannelHandle> PushChannel(
      int flags, const std::shared_ptr<Channel>& channel, int* channel_id);

  /*
   * Create a new channel and push it as a file descriptor to the client. See
   * Service::PushChannel() for a detail description of this method's operation.
   */
  Status<RemoteChannelHandle> PushChannel(
      Service* service, int flags, const std::shared_ptr<Channel>& channel,
      int* channel_id);

  /*
   * Check whether the |ref| is a reference to channel to this service.
   * If the channel reference in question is valid, the Channel object is
   * returned in |channel| when non-nullptr.
   *
   * Return values:
   *  channel_id - id of the channel if the |ref| is a valid reference to
   *               this service's channel.
   * Errors:
   *  EOPNOTSUPP - the file descriptor is not a channel or is a channel to
   *  another service.
   *  EBADF - the file descriptor is invalid.
   *  FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
   *  memory addresses.
   *  EINVAL - the value of |ref| is invalid or the message id for this
   *           message is no longer valid.
   */
  Status<int> CheckChannel(ChannelReference ref,
                           std::shared_ptr<Channel>* channel) const;

  /*
   * Overload of CheckChannel() that checks whether the channel reference is for
   * a channel to the service |service|.
   */
  Status<int> CheckChannel(const Service* service, ChannelReference ref,
                           std::shared_ptr<Channel>* channel) const;

  /*
   * Overload of CheckChannel() that automatically converts to shared pointers
   * to types derived from Channel.
   */
  template <class C>
  Status<int> CheckChannel(ChannelReference ref,
                           std::shared_ptr<C>* channel) const {
    std::shared_ptr<Channel> base_pointer;
    const Status<int> ret =
        CheckChannel(ref, channel ? &base_pointer : nullptr);
    if (channel)
      *channel = std::static_pointer_cast<C>(base_pointer);
    return ret;
  }

  template <class C>
  Status<int> CheckChannel(const Service* service, ChannelReference ref,
                           std::shared_ptr<C>* channel) const {
    std::shared_ptr<Channel> base_pointer;
    const Status<int> ret =
        CheckChannel(service, ref, channel ? &base_pointer : nullptr);
    if (channel)
      *channel = std::static_pointer_cast<C>(base_pointer);
    return ret;
  }

  /*
   * MessageInfo accessors.
   */
  pid_t GetProcessId() const;
  pid_t GetThreadId() const;
  uid_t GetEffectiveUserId() const;
  gid_t GetEffectiveGroupId() const;
  int GetChannelId() const;
  int GetMessageId() const;
  int GetOp() const;
  int GetFlags() const;
  size_t GetSendLength() const;
  size_t GetReceiveLength() const;
  size_t GetFileDescriptorCount() const;

  /*
   * Impulses are asynchronous and cannot be replied to. All impulses have this
   * invalid message id.
   */
  enum { IMPULSE_MESSAGE_ID = -1 };

  /*
   * Returns true if this Message describes an asynchronous "impulse" message.
   */
  bool IsImpulse() const { return GetMessageId() == IMPULSE_MESSAGE_ID; }

  /*
   * Returns a pointer to the impulse payload. Impulses are a maximum of 32
   * bytes in size and the start of the impulse payload is guaranteed to be
   * 8-byte aligned. Use GetSendLength() to determine the payload size.
   */
  const std::uint8_t* ImpulseBegin() const;

  /*
   * Returns one byte past the end of the impulse payload, as conventional for
   * STL iterators.
   */
  const std::uint8_t* ImpulseEnd() const;

  /*
   * Get/set the Channel object for the channel associated
   * with this message. It is up to the caller to synchronize
   * these in multi-threaded services.
   */
  std::shared_ptr<Channel> GetChannel() const;
  Status<void> SetChannel(const std::shared_ptr<Channel>& channnel);

  /*
   * Get the Channel object for the channel associated with this message,
   * automatically converted to the desired subclass of Channel.
   */
  template <class C>
  std::shared_ptr<C> GetChannel() const {
    return std::static_pointer_cast<C>(GetChannel());
  }

  /*
   * Gets the service this message was received on. Returns nullptr if the
   * service was destroyed.
   */
  std::shared_ptr<Service> GetService() const;

  /*
   * Raw access to the MessageInfo for this message.
   */
  const MessageInfo& GetInfo() const;

  bool replied() const { return replied_; }
  bool IsChannelExpired() const { return channel_.expired(); }
  bool IsServiceExpired() const { return service_.expired(); }

  /*
   * Returns true if the message is non-empty; that is the message can be
   * replied to using this instance.
   */
  explicit operator bool() const { return !replied_; }

  const void* GetState() const { return state_; }
  void* GetState() { return state_; }

 private:
  friend class Service;

  Message(const Message&) = delete;
  void operator=(const Message&) = delete;
  void Destroy();

  std::weak_ptr<Service> service_;
  std::weak_ptr<Channel> channel_;
  MessageInfo info_;
  void* state_{nullptr};
  bool replied_;
};

// Base class for RPC services.
class Service : public std::enable_shared_from_this<Service> {
 public:
  Service(const std::string& name, std::unique_ptr<Endpoint> endpoint);
  virtual ~Service();

  /*
   * Utility to get a shared_ptr reference from the service context pointer.
   */
  static std::shared_ptr<Service> GetFromMessageInfo(const MessageInfo& info);

  /*
   * Returns whether initialization was successful. Subclasses that override
   * this must call this base method and AND the results with their own. This
   * method is not intended to do any initialization work itself, only to
   * signal success or failure.
   */
  virtual bool IsInitialized() const;

  /*
   * Called by defaultHandleMessage in response to a CHANNEL_OPEN message.
   * This gives subclasses of Service a convenient hook to create per-channel
   * context in the form of a Channel subclass.
   *
   * The Channel instance returned by this is used to set the channel context
   * pointer for the channel that was just opened.
   */
  virtual std::shared_ptr<Channel> OnChannelOpen(Message& message);

  /*
   * Called by defaultHandleMessage in response to a CHANNEL_CLOSE message.
   * This give subclasses of Service a convenient hook to clean up per-channel
   * context.
   */
  virtual void OnChannelClose(Message& message,
                              const std::shared_ptr<Channel>& channel);

  /*
   * Set the channel context for the given channel. This keeps a reference to
   * the Channel object until the channel is closed or another call replaces
   * the current value.
   */
  Status<void> SetChannel(int channel_id,
                          const std::shared_ptr<Channel>& channel);

  /*
   * Get the channel context for the given channel id. This method should be
   * used sparingly because of the performance characteristics of the underlying
   * map; it is intended for limited, non-critical path access from outside of
   * message dispatch. In most cases lookup by id should be unnecessary in a
   * properly designed service; Message::GetChannel() should be used instead
   * whenever an operation is in the context of a message.
   *
   * Again, if you lookup a channel context object for a service by id in a
   * message handling path for the same service, you're probably doing something
   * wrong.
   */
  std::shared_ptr<Channel> GetChannel(int channel_id) const;

  /*
   * Get a snapshot of the active channels for this service. This is the
   * preferred way to access the set of channels because it avoids potential
   * deadlocks and race conditions that may occur when operating on the channel
   * map directly. However, it is more expensive than direct iteration because
   * of dynamic memory allocation and shared pointer reference costs.
   *
   * Automatically converts returned items to shared pointers of the type
   * std::shared_ptr<C>, where C is the subclass of Channel used by the service.
   */
  template <class C>
  std::vector<std::shared_ptr<C>> GetChannels() const {
    std::lock_guard<std::mutex> autolock(channels_mutex_);
    std::vector<std::shared_ptr<C>> items;
    items.reserve(channels_.size());

    for (const auto& pair : channels_) {
      items.push_back(std::static_pointer_cast<C>(pair.second));
    }

    return items;
  }

  /*
   * Close a channel, signaling the client file object and freeing the channel
   * id. Once closed, the client side of the channel always returns the error
   * ESHUTDOWN and signals the poll/epoll events POLLHUP and POLLFREE.
   *
   * The internal reference to the Channel instance associated with the channel
   * is removed, which may result in the Channel object being freed.
   *
   * OnChannelClosed is not called in response to this method call.
   */
  Status<void> CloseChannel(int channel_id);

  /*
   * Update the event bits for the given channel (given by id), using the
   * given clear and set masks.
   *
   * This is useful for asynchronously signaling events that clients may be
   * waiting for using select/poll/epoll.
   */
  Status<void> ModifyChannelEvents(int channel_id, int clear_mask,
                                   int set_mask);

  /*
   * Create a new channel and push it as a file descriptor to the process
   * sending the |message|. |flags| may be set to O_NONBLOCK and/or
   * O_CLOEXEC to control the initial behavior of the new file descriptor (the
   * sending process may change these later using fcntl()). The internal Channel
   * instance associated with this channel is set to |channel|, which may be
   * nullptr. The new channel id allocated for this channel is returned in
   * |channel_id|, which may also be nullptr if not needed.
   *
   * On success, returns the remote channel handle for the new channel in the
   * sending process' handle space. This MUST be returned to the sender via
   * Message::Reply(), Message::Write(), or Message::WriteVector().
   *
   * On error, returns an errno code describing the cause of the error.
   *
   * Service::OnChannelCreate() is not called in response to the creation of the
   * new channel.
   */
  Status<RemoteChannelHandle> PushChannel(
      Message* message, int flags, const std::shared_ptr<Channel>& channel,
      int* channel_id);

  /*
   * Check whether the |ref| is a reference to a channel to this service.
   * If the channel reference in question is valid, the Channel object is
   * returned in |channel| when non-nullptr.
   *
   * Return values:
   *  channel_id - id of the channel if the channel reference.
   * Errors:
   *  EOPNOTSUPP - the file descriptor is not a channel or is a channel to
   *  another service.
   *  EBADF - the file descriptor is invalid.
   *  FAULT - |channel_id| or |channel| are non-nullptr and point to invalid
   *  memory addresses.
   *  EINVAL - the value of |ref| is invalid or the message id for this
   *  message is no longer valid.
   */
  Status<int> CheckChannel(const Message* message, ChannelReference ref,
                           std::shared_ptr<Channel>* channel) const;

  /*
   * Overload of CheckChannel() that automatically converts to shared pointers
   * of types derived from Channel.
   */
  template <class C>
  Status<int> CheckChannel(const Message* message, ChannelReference ref,
                           std::shared_ptr<C>* channel) const {
    std::shared_ptr<Channel> base_pointer;
    const Status<int> ret =
        CheckChannel(message, ref, channel ? &base_pointer : nullptr);
    if (channel)
      *channel = std::static_pointer_cast<C>(base_pointer);
    return ret;
  }

  /*
   * Handle a message. Subclasses override this to receive messages and decide
   * how to dispatch them.
   *
   * The default implementation simply calls defaultHandleMessage().
   * Subclasses should call the same for any unrecognized message opcodes.
   */
  virtual Status<void> HandleMessage(Message& message);

  /*
   * Handle an asynchronous message. Subclasses override this to receive
   * asynchronous "impulse" messages. Impulses have a limited-size payload that
   * is transferred upfront with the message description.
   */
  virtual void HandleImpulse(Message& impulse);

  /*
   * The default message handler. It is important that all messages
   * (eventually) get a reply. This method should be called by subclasses for
   * any unrecognized opcodes or otherwise unhandled messages to prevent
   * erroneous requests from blocking indefinitely.
   *
   * Provides default handling of CHANNEL_OPEN and CHANNEL_CLOSE, calling
   * OnChannelOpen() and OnChannelClose(), respectively.
   *
   * For all other message opcodes, this method replies with ENOTSUP.
   */
  Status<void> DefaultHandleMessage(Message& message);

  /*
   * Called when system properties have changed. Subclasses should implement
   * this method if they need to handle when system properties change.
   */
  virtual void OnSysPropChange();

  /*
   * Get the endpoint for the service.
   */
  Endpoint* endpoint() const { return endpoint_.get(); }

  /*
   * Cancels the endpoint, unblocking any receiver threads waiting in
   * ReceiveAndDispatch().
   */
  Status<void> Cancel();

  /*
   * Iterator type for Channel map iterators.
   */
  using ChannelIterator =
      std::unordered_map<int, std::shared_ptr<Channel>>::iterator;

  /*
   * Iterates over the Channel map and performs the action given by |action| on
   * each channel map item (const ChannelIterator::value_type).
   * |channels_mutex_| is not held; it is the responsibility of the caller to
   * ensure serialization between threads that modify or iterate over the
   * Channel map.
   */
  template <class A>
  void ForEachChannelUnlocked(A action) const {
    std::for_each(channels_.begin(), channels_.end(), action);
  }

  /*
   * Iterates over the Channel map and performs the action given by |action| on
   * each channel map item (const ChannelIterator::value_type).
   * |channels_mutex_| is held to serialize access to the map; care must be
   * taken to avoid recursively acquiring the mutex, for example, by calling
   * Service::{GetChannel,SetChannel,CloseChannel,PushChannel}() or
   * Message::SetChannel() in the action.
   */
  template <class A>
  void ForEachChannel(A action) const {
    std::lock_guard<std::mutex> autolock(channels_mutex_);
    ForEachChannelUnlocked(action);
  }

  /*
   * Subclasses of Service may override this method to provide a text string
   * describing the state of the service. This method is called by
   * HandleSystemMessage in response to the standard
   * DUMP_STATE message. The string returned to the dump state client is
   * truncated to |max_length| and reflects the maximum size the client can
   * handle.
   */
  virtual std::string DumpState(size_t max_length);

  /*
   * Receives a message on this Service instance's endpoint and dispatches it.
   * If the endpoint is in blocking mode this call blocks until a message is
   * received, a signal is delivered to this thread, or the service is canceled.
   * If the endpoint is in non-blocking mode and a message is not pending this
   * call returns immediately with ETIMEDOUT.
   */
  Status<void> ReceiveAndDispatch();

 private:
  friend class Message;

  Status<void> HandleSystemMessage(Message& message);

  Service(const Service&);
  void operator=(const Service&) = delete;

  const std::string name_;
  std::unique_ptr<Endpoint> endpoint_;

  /*
   * Maintains references to active channels.
   */
  mutable std::mutex channels_mutex_;
  std::unordered_map<int, std::shared_ptr<Channel>> channels_;
};

/*
 * Utility base class for services. This template handles allocation and
 * initialization checks, reducing boiler plate code.
 */
template <typename TYPE>
class ServiceBase : public Service {
 public:
  /*
   * Static service allocation method that check for initialization errors.
   * If errors are encountered these automatically clean up and return
   * nullptr.
   */
  template <typename... Args>
  static inline std::shared_ptr<TYPE> Create(Args&&... args) {
    std::shared_ptr<TYPE> service(new TYPE(std::forward<Args>(args)...));
    if (service->IsInitialized())
      return service;
    else
      return nullptr;
  }

 protected:
  /*
   * Shorthand for subclasses to refer to this base, particularly
   * to call the base class constructor.
   */
  typedef ServiceBase<TYPE> BASE;

  ServiceBase(const std::string& name, std::unique_ptr<Endpoint> endpoint)
      : Service(name, std::move(endpoint)) {}
};

#ifndef STRINGIFY
#define STRINGIFY2(s) #s
#define STRINGIFY(s) STRINGIFY2(s)
#endif

#define PDX_ERROR_PREFIX "[" __FILE__ ":" STRINGIFY(__LINE__) "]"

/*
 * Macros for replying to messages. Error handling can be tedious;
 * these macros make things a little cleaner.
 */
#define CHECK_ERROR(cond, error, fmt, ...) \
  do {                                     \
    if ((cond)) {                          \
      ALOGE(fmt, ##__VA_ARGS__);           \
      goto error;                          \
    }                                      \
  } while (0)

#define REPLY_ERROR(message, error, error_label)                              \
  do {                                                                        \
    auto __status = message.ReplyError(error);                                \
    CHECK_ERROR(!__status, error_label,                                       \
                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
                __status.GetErrorMessage().c_str());                          \
    goto error_label;                                                         \
  } while (0)

#define REPLY_ERROR_RETURN(message, error, ...)                          \
  do {                                                                   \
    auto __status = message.ReplyError(error);                           \
    ALOGE_IF(!__status,                                                  \
             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
             __status.GetErrorMessage().c_str());                        \
    return __VA_ARGS__;                                                  \
  } while (0)

#define REPLY_MESSAGE(message, message_return_code, error_label)              \
  do {                                                                        \
    auto __status = message.Reply(message_return_code);                       \
    CHECK_ERROR(!__status, error_label,                                       \
                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
                __status.GetErrorMessage().c_str());                          \
    goto error_label;                                                         \
  } while (0)

#define REPLY_SUCCESS(message, message_return_code, error_label) \
  REPLY_MESSAGE(message, message_return_code, error_label)

#define REPLY_MESSAGE_RETURN(message, message_return_code, ...)          \
  do {                                                                   \
    auto __status = message.Reply(message_return_code);                  \
    ALOGE_IF(!__status,                                                  \
             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
             __status.GetErrorMessage().c_str());                        \
    return __VA_ARGS__;                                                  \
  } while (0)

#define REPLY_SUCCESS_RETURN(message, message_return_code, ...) \
  REPLY_MESSAGE_RETURN(message, message_return_code, __VA_ARGS__)

#define REPLY_FD(message, push_fd, error_label)                               \
  do {                                                                        \
    auto __status = message.ReplyFileDescriptor(push_fd);                     \
    CHECK_ERROR(!__status, error_label,                                       \
                PDX_ERROR_PREFIX " Failed to reply to message because: %s\n", \
                __status.GetErrorMessage().c_str());                          \
    goto error_label;                                                         \
  } while (0)

#define REPLY_FD_RETURN(message, push_fd, ...)                           \
  do {                                                                   \
    auto __status = message.ReplyFileDescriptor(push_fd);                \
    ALOGE_IF(__status < 0,                                               \
             PDX_ERROR_PREFIX " Failed to reply to message because: %s", \
             __status.GetErrorMessage().c_str());                        \
    return __VA_ARGS__;                                                  \
  } while (0)

}  // namespace pdx
}  // namespace android

#endif  // ANDROID_PDX_SERVICE_H_
