/*
 * Copyright (C) 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// TODO: We can't use std::shared_ptr on the older guests due to HALs.

#ifndef CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_
#define CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_

#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/timerfd.h>
#include <sys/uio.h>
#include <sys/un.h>

#include <memory>

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>

#include "common/libs/auto_resources/auto_resources.h"

/**
 * Classes to to enable safe access to files.
 * POSIX kernels have an unfortunate habit of recycling file descriptors.
 * That can cause problems like http://b/26121457 in code that doesn't manage
 * file lifetimes properly. These classes implement an alternate interface
 * that has some advantages:
 *
 * o References to files are tightly controlled
 * o Files are auto-closed if they go out of scope
 * o Files are life-time aware. It is impossible to close the instance twice.
 * o File descriptors are always initialized. By default the descriptor is
 *   set to a closed instance.
 *
 * These classes are designed to mimic to POSIX interface as closely as
 * possible. Specifically, they don't attempt to track the type of file
 * descriptors and expose only the valid operations. This is by design, since
 * it makes it easier to convert existing code to SharedFDs and avoids the
 * possibility that new POSIX functionality will lead to large refactorings.
 */
namespace cvd {

class FileInstance;

/**
 * Describes the fields in msghdr that are honored by the *MsgAndFDs
 * calls.
 */
struct InbandMessageHeader {
  void* msg_name;
  socklen_t msg_namelen;
  struct iovec* msg_iov;
  size_t msg_iovlen;
  int msg_flags;

  void Convert(struct msghdr* dest) const {
    dest->msg_name = msg_name;
    dest->msg_namelen = msg_namelen;
    dest->msg_iov = msg_iov;
    dest->msg_iovlen = msg_iovlen;
    dest->msg_flags = msg_flags;
  }
};

/**
 * Counted reference to a FileInstance.
 *
 * This is also the place where most new FileInstances are created. The creation
 * mehtods correspond to the underlying POSIX calls.
 *
 * SharedFDs can be compared and stored in STL containers. The semantics are
 * slightly different from POSIX file descriptors:
 *
 * o The value of the SharedFD is the identity of its underlying FileInstance.
 *
 * o Each newly created SharedFD has a unique, closed FileInstance:
 *    SharedFD a, b;
 *    assert (a != b);
 *    a = b;
 *    asssert(a == b);
 *
 * o The identity of the FileInstance is not affected by closing the file:
 *   SharedFD a, b;
 *   set<SharedFD> s;
 *   s.insert(a);
 *   assert(s.count(a) == 1);
 *   assert(s.count(b) == 0);
 *   a->Close();
 *   assert(s.count(a) == 1);
 *   assert(s.count(b) == 0);
 *
 * o FileInstances are never visibly recycled.
 *
 * o If all of the SharedFDs referring to a FileInstance go out of scope the
 *   file is closed and the FileInstance is recycled.
 *
 * Creation methods must ensure that no references to the new file descriptor
 * escape. The underlying FileInstance should have the only reference to the
 * file descriptor. Any method that needs to know the fd must be in either
 * SharedFD or FileInstance.
 *
 * SharedFDs always have an underlying FileInstance, so all of the method
 * calls are safe in accordance with the null object pattern.
 *
 * Errors on system calls that create new FileInstances, such as Open, are
 * reported with a new, closed FileInstance with the errno set.
 */
class SharedFD {
 public:
  inline SharedFD();
  SharedFD(const std::shared_ptr<FileInstance>& in) : value_(in) {}
  // Reference the listener as a FileInstance to make this FD type agnostic.
  static SharedFD Accept(const FileInstance& listener, struct sockaddr* addr,
                         socklen_t* addrlen);
  static SharedFD Accept(const FileInstance& listener);
  static SharedFD Dup(int unmanaged_fd);
  static SharedFD GetControlSocket(const char* name);
  // Returns false on failure, true on success.
  static SharedFD Open(const char* pathname, int flags, mode_t mode = 0);
  static bool Pipe(SharedFD* fd0, SharedFD* fd1);
  static SharedFD Event(int initval = 0, int flags = 0);
  static SharedFD Epoll(int flags = 0);
  static bool SocketPair(int domain, int type, int protocol, SharedFD* fd0,
                         SharedFD* fd1);
  static SharedFD Socket(int domain, int socket_type, int protocol);
  static SharedFD SocketLocalClient(const char* name, bool is_abstract,
                                    int in_type);
  static SharedFD SocketLocalClient(int port, int type);
  static SharedFD SocketLocalServer(const char* name, bool is_abstract,
                                    int in_type, mode_t mode);
  static SharedFD SocketLocalServer(int port, int type);
  static SharedFD SocketSeqPacketServer(const char* name, mode_t mode);
  static SharedFD SocketSeqPacketClient(const char* name);
  static SharedFD TimerFD(int clock, int flags);

  bool operator==(const SharedFD& rhs) const { return value_ == rhs.value_; }

  bool operator!=(const SharedFD& rhs) const { return value_ != rhs.value_; }

  bool operator<(const SharedFD& rhs) const { return value_ < rhs.value_; }

  bool operator<=(const SharedFD& rhs) const { return value_ <= rhs.value_; }

  bool operator>(const SharedFD& rhs) const { return value_ > rhs.value_; }

  bool operator>=(const SharedFD& rhs) const { return value_ >= rhs.value_; }

  std::shared_ptr<FileInstance> operator->() const { return value_; }

  const cvd::FileInstance& operator*() const { return *value_; }

  cvd::FileInstance& operator*() { return *value_; }

 private:
  std::shared_ptr<FileInstance> value_;
};

/**
 * Tracks the lifetime of a file descriptor and provides methods to allow
 * callers to use the file without knowledge of the underlying descriptor
 * number.
 *
 * FileInstances have two states: Open and Closed. They may start in either
 * state. However, once a FileIntance enters the Closed state it cannot be
 * reopened.
 *
 * Construction of FileInstances is limited to select classes to avoid
 * escaping file descriptors. At this point SharedFD is the only class
 * that has access. We may eventually have ScopedFD and WeakFD.
 */
class FileInstance {
  // Give SharedFD access to the aliasing constructor.
  friend class SharedFD;

 public:
  virtual ~FileInstance() { Close(); }

  // This can't be a singleton because our shared_ptr's aren't thread safe.
  static std::shared_ptr<FileInstance> ClosedInstance() {
    return std::shared_ptr<FileInstance>(new FileInstance(-1, EBADF));
  }

  int Bind(const struct sockaddr* addr, socklen_t addrlen) {
    errno = 0;
    int rval = bind(fd_, addr, addrlen);
    errno_ = errno;
    return rval;
  }

  int Connect(const struct sockaddr* addr, socklen_t addrlen) {
    errno = 0;
    int rval = connect(fd_, addr, addrlen);
    errno_ = errno;
    return rval;
  }

  void Close();

  // Returns true if the entire input was copied.
  // Otherwise an error will be set either on this file or the input.
  // The non-const reference is needed to avoid binding this to a particular
  // reference type.
  bool CopyFrom(FileInstance& in);

  int UNMANAGED_Dup() {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(dup(fd_));
    errno_ = errno;
    return rval;
  }

  int EpollCtl(int op, cvd::SharedFD new_fd, struct epoll_event* event) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(epoll_ctl(fd_, op, new_fd->fd_, event));
    errno_ = errno;
    return rval;
  }

  int EpollWait(struct epoll_event* events, int maxevents, int timeout) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(epoll_wait(fd_, events, maxevents, timeout));
    errno_ = errno;
    return rval;
  }

  int Fchown(uid_t owner, gid_t group) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(fchown(fd_, owner, group));
    errno_ = errno;
    return rval;
  }

  int Fcntl(int command, int value) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(fcntl(fd_, command, value));
    errno_ = errno;
    return rval;
  }

  int Fstat(struct stat* buf) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(fstat(fd_, buf));
    errno_ = errno;
    return rval;
  }

  int GetErrno() const { return errno_; }

  int GetSockOpt(int level, int optname, void* optval, socklen_t* optlen) {
    errno = 0;
    int rval = getsockopt(fd_, level, optname, optval, optlen);
    if (rval == -1) {
      errno_ = errno;
    }
    return rval;
  }

  void Identify(const char* identity);

  int Ioctl(int request, void* val = nullptr) {
    errno = 0;
    int rval = TEMP_FAILURE_RETRY(ioctl(fd_, request, val));
    errno_ = errno;
    return rval;
  }

  bool IsOpen() const { return fd_ != -1; }

  // in probably isn't modified, but the API spec doesn't have const.
  bool IsSet(fd_set* in) const;

  int Listen(int backlog) {
    errno = 0;
    int rval = listen(fd_, backlog);
    errno_ = errno;
    return rval;
  }

  static void Log(const char* message);

  off_t LSeek(off_t offset, int whence) {
    errno = 0;
    off_t rval = TEMP_FAILURE_RETRY(lseek(fd_, offset, whence));
    errno_ = errno;
    return rval;
  }

  void* Mmap(void* addr, size_t length, int prot, int flags, off_t offset) {
    errno = 0;
    void* rval = mmap(addr, length, prot, flags, fd_, offset);
    errno_ = errno;
    return rval;
  }

  ssize_t Pread(void* buf, size_t count, off_t offset) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(pread(fd_, buf, count, offset));
    errno_ = errno;
    return rval;
  }

  ssize_t Recv(void* buf, size_t len, int flags) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(recv(fd_, buf, len, flags));
    errno_ = errno;
    return rval;
  }

  ssize_t RecvFrom(void* buf, size_t len, int flags, struct sockaddr* src_addr,
                   socklen_t* addr_len) {
    errno = 0;
    ssize_t rval =
        TEMP_FAILURE_RETRY(recvfrom(fd_, buf, len, flags, src_addr, addr_len));
    errno_ = errno;
    return rval;
  }

  ssize_t RecvMsg(struct msghdr* msg, int flags) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(recvmsg(fd_, msg, flags));
    errno_ = errno;
    return rval;
  }

  template <size_t SZ>
  ssize_t RecvMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags,
                        SharedFD (*new_fds)[SZ]) {
    // We need to make some modifications to land the fds. Make it clear
    // that there are no updates to the msg being passed in during this call.
    struct msghdr msg;
    msg_in.Convert(&msg);
    union {
      char buffer[CMSG_SPACE(SZ * sizeof(int))];
      struct cmsghdr this_aligns_buffer;
    } u;
    msg.msg_control = u.buffer;
    msg.msg_controllen = sizeof(u.buffer);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg));
    for (size_t i = 0; i < SZ; ++i) {
      fd_array[i] = -1;
    }
    ssize_t rval = RecvMsg(&msg, flags);
    for (size_t i = 0; i < SZ; ++i) {
      (*new_fds)[i] =
          std::shared_ptr<FileInstance>(new FileInstance(fd_array[i], errno));
    }
    return rval;
  }

  ssize_t Read(void* buf, size_t count) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(read(fd_, buf, count));
    errno_ = errno;
    return rval;
  }

  ssize_t Send(const void* buf, size_t len, int flags) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(send(fd_, buf, len, flags));
    errno_ = errno;
    return rval;
  }

  ssize_t SendMsg(const struct msghdr* msg, int flags) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(sendmsg(fd_, msg, flags));
    errno_ = errno;
    return rval;
  }

  template <size_t SZ>
  ssize_t SendMsgAndFDs(const struct InbandMessageHeader& msg_in, int flags,
                        const SharedFD (&fds)[SZ]) {
    struct msghdr msg;
    msg_in.Convert(&msg);
    union {
      char buffer[CMSG_SPACE(SZ * sizeof(int))];
      struct cmsghdr this_aligns_buffer;
    } u;
    msg.msg_control = u.buffer;
    msg.msg_controllen = sizeof(u.buffer);

    cmsghdr* cmsg = CMSG_FIRSTHDR(&msg);
    cmsg->cmsg_len = CMSG_LEN(SZ * sizeof(int));
    cmsg->cmsg_level = SOL_SOCKET;
    cmsg->cmsg_type = SCM_RIGHTS;
    int* fd_array = reinterpret_cast<int*>(CMSG_DATA(cmsg));
    for (size_t i = 0; i < SZ; ++i) {
      fd_array[i] = fds[i]->fd_;
    }
    return SendMsg(&msg, flags);
  }

  int Shutdown(int how) {
    errno = 0;
    int rval = shutdown(fd_, how);
    errno_ = errno;
    return rval;
  }

  ssize_t SendTo(const void* buf, size_t len, int flags,
                 const struct sockaddr* dest_addr, socklen_t addrlen) {
    errno = 0;
    ssize_t rval =
        TEMP_FAILURE_RETRY(sendto(fd_, buf, len, flags, dest_addr, addrlen));
    errno_ = errno;
    return rval;
  }

  void Set(fd_set* dest, int* max_index) const;

  int SetSockOpt(int level, int optname, const void* optval, socklen_t optlen) {
    errno = 0;
    int rval = setsockopt(fd_, level, optname, optval, optlen);
    errno_ = errno;
    return rval;
  }

  const char* StrError() const {
    errno = 0;
    FileInstance* s = const_cast<FileInstance*>(this);
    char* out = strerror_r(errno_, s->strerror_buf_, sizeof(strerror_buf_));

    // From man page:
    //  strerror_r() returns a pointer to a string containing the error message.
    //  This may be either a pointer to a string that the function stores in
    //  buf, or a pointer to some (immutable) static string (in which case buf
    //  is unused).
    if (out != s->strerror_buf_) {
      strncpy(s->strerror_buf_, out, sizeof(strerror_buf_));
    }
    return strerror_buf_;
  }

  int TimerGet(struct itimerspec* curr_value) {
    errno = 0;
    int rval = timerfd_gettime(fd_, curr_value);
    errno_ = errno;
    return rval;
  }

  int TimerSet(int flags, const struct itimerspec* new_value,
               struct itimerspec* old_value) {
    errno = 0;
    int rval = timerfd_settime(fd_, flags, new_value, old_value);
    errno_ = errno;
    return rval;
  }

  ssize_t Truncate(off_t length) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(ftruncate(fd_, length));
    errno_ = errno;
    return rval;
  }

  ssize_t Write(const void* buf, size_t count) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(write(fd_, buf, count));
    errno_ = errno;
    return rval;
  }

  ssize_t WriteV(struct iovec* iov, int iovcount) {
    errno = 0;
    ssize_t rval = TEMP_FAILURE_RETRY(writev(fd_, iov, iovcount));
    errno_ = errno;
    return rval;
  }

 private:
  FileInstance(int fd, int in_errno) : fd_(fd), errno_(in_errno) {
    identity_.PrintF("fd=%d @%p", fd, this);
  }

  FileInstance* Accept(struct sockaddr* addr, socklen_t* addrlen) const {
    int fd = TEMP_FAILURE_RETRY(accept(fd_, addr, addrlen));
    if (fd == -1) {
      return new FileInstance(fd, errno);
    } else {
      return new FileInstance(fd, 0);
    }
  }

  int fd_;
  int errno_;
  AutoFreeBuffer identity_;
  char strerror_buf_[160];
};

/* Methods that need both a fully defined SharedFD and a fully defined
   FileInstance. */

SharedFD::SharedFD() : value_(FileInstance::ClosedInstance()) {}

}  // namespace cvd

#endif  // CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_
