/*
 * 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 <sstream>
#include <vector>

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

#include <android-base/cmsg.h>

#include "vm_sockets.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 cuttlefish {

struct PollSharedFd;
class Epoll;
class FileInstance;

/**
 * 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 {
  // Give WeakFD access to the underlying shared_ptr.
  friend class WeakFD;
 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);
  // All SharedFDs have the O_CLOEXEC flag after creation. To remove use the
  // Fcntl or Dup functions.
  static SharedFD Open(const std::string& pathname, int flags, mode_t mode = 0);
  static SharedFD Creat(const std::string& pathname, mode_t mode);
  static int Fchdir(SharedFD);
  static SharedFD Fifo(const std::string& pathname, mode_t mode);
  static bool Pipe(SharedFD* fd0, SharedFD* fd1);
  static SharedFD Event(int initval = 0, int flags = 0);
  static SharedFD MemfdCreate(const std::string& name, unsigned int flags = 0);
  static SharedFD MemfdCreateWithData(const std::string& name, const std::string& data, unsigned int flags = 0);
  static SharedFD Mkstemp(std::string* path);
  static int Poll(PollSharedFd* fds, size_t num_fds, int timeout);
  static int Poll(std::vector<PollSharedFd>& fds, int timeout);
  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 std::string& name, bool is_abstract,
                                    int in_type);
  static SharedFD SocketLocalClient(const std::string& name, bool is_abstract,
                                    int in_type, int timeout_seconds);
  static SharedFD SocketLocalClient(int port, int type);
  static SharedFD SocketLocalServer(const std::string& name, bool is_abstract,
                                    int in_type, mode_t mode);
  static SharedFD SocketLocalServer(int port, int type);
  static SharedFD VsockServer(unsigned int port, int type,
                              unsigned int cid = VMADDR_CID_ANY);
  static SharedFD VsockServer(int type);
  static SharedFD VsockClient(unsigned int cid, unsigned int port, int type);

  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 FileInstance& operator*() const { return *value_; }

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

 private:
  static SharedFD ErrorFD(int error);

  std::shared_ptr<FileInstance> value_;
};

/**
 * A non-owning reference to a FileInstance. The referenced FileInstance needs
 * to be managed by a SharedFD. A WeakFD needs to be converted to a SharedFD to
 * access the underlying FileInstance.
 */
class WeakFD {
 public:
  WeakFD(SharedFD shared_fd) : value_(shared_fd.value_) {}

  // Creates a new SharedFD object that shares ownership of the underlying fd.
  // Callers need to check that the returned SharedFD is open before using it.
  SharedFD lock() const;

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

// Provides RAII semantics for memory mappings, preventing memory leaks. It does
// not however prevent use-after-free errors since the underlying pointer can be
// extracted and could survive this object.
class ScopedMMap {
 public:
  ScopedMMap();
  ScopedMMap(void* ptr, size_t size);
  ScopedMMap(const ScopedMMap& other) = delete;
  ScopedMMap& operator=(const ScopedMMap& other) = delete;
  ScopedMMap(ScopedMMap&& other);

  ~ScopedMMap();

  void* get() { return ptr_; }
  const void* get() const { return ptr_; }
  size_t len() const { return len_; }

  operator bool() const { return ptr_ != MAP_FAILED; }

 private:
  void* ptr_ = MAP_FAILED;
  size_t len_;
};

/**
 * 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;
  friend class Epoll;

 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();

  int Bind(const struct sockaddr* addr, socklen_t addrlen);
  int Connect(const struct sockaddr* addr, socklen_t addrlen);
  int ConnectWithTimeout(const struct sockaddr* addr, socklen_t addrlen,
                         struct timeval* timeout);
  void Close();

  bool Chmod(mode_t mode);

  // 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, size_t length);
  // Same as CopyFrom, but reads from input until EOF is reached.
  bool CopyAllFrom(FileInstance& in);

  int UNMANAGED_Dup();
  int UNMANAGED_Dup2(int newfd);
  int Fchdir();
  int Fcntl(int command, int value);

  int Flock(int operation);

  int GetErrno() const { return errno_; }
  int GetSockName(struct sockaddr* addr, socklen_t* addrlen);

  unsigned int VsockServerPort();

  int Ioctl(int request, void* val = nullptr);
  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;

  // whether this is a regular file or not
  bool IsRegular() const { return is_regular_file_; }

  /**
   * Adds a hard link to a file descriptor, based on the current working
   * directory of the process or to some absolute path.
   *
   * https://www.man7.org/linux/man-pages/man2/linkat.2.html
   *
   * Using this on a file opened with O_TMPFILE can link it into the filesystem.
   */
  // Used with O_TMPFILE files to attach them to the filesystem.
  int LinkAtCwd(const std::string& path);
  int Listen(int backlog);
  static void Log(const char* message);
  off_t LSeek(off_t offset, int whence);
  ssize_t Recv(void* buf, size_t len, int flags);
  ssize_t RecvMsg(struct msghdr* msg, int flags);
  ssize_t Read(void* buf, size_t count);
  int EventfdRead(eventfd_t* value);
  ssize_t Send(const void* buf, size_t len, int flags);
  ssize_t SendMsg(const struct msghdr* msg, int flags);

  template <typename... Args>
  ssize_t SendFileDescriptors(const void* buf, size_t len, Args&&... sent_fds) {
    std::vector<int> fds;
    android::base::Append(fds, std::forward<int>(sent_fds->fd_)...);
    errno = 0;
    auto ret = android::base::SendFileDescriptorVector(fd_, buf, len, fds);
    errno_ = errno;
    return ret;
  }

  int Shutdown(int how);
  void Set(fd_set* dest, int* max_index) const;
  int SetSockOpt(int level, int optname, const void* optval, socklen_t optlen);
  int GetSockOpt(int level, int optname, void* optval, socklen_t* optlen);
  int SetTerminalRaw();
  std::string StrError() const;
  ScopedMMap MMap(void* addr, size_t length, int prot, int flags, off_t offset);
  ssize_t Truncate(off_t length);
  /*
   * If the file is a regular file and the count is 0, Write() may detect
   * error(s) by calling write(fd, buf, 0) declared in <unistd.h>. If detected,
   * it will return -1. If not, 0 will be returned. For non-regular files such
   * as socket or pipe, write(fd, buf, 0) is not specified. Write(), however,
   * will do nothing and just return 0.
   *
   */
  ssize_t Write(const void* buf, size_t count);
  int EventfdWrite(eventfd_t value);
  bool IsATTY();

 private:
  FileInstance(int fd, int in_errno);
  FileInstance* Accept(struct sockaddr* addr, socklen_t* addrlen) const;

  int fd_;
  int errno_;
  std::string identity_;
  bool is_regular_file_;
};

struct PollSharedFd {
  SharedFD fd;
  short events;
  short revents;
};

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

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

}  // namespace cuttlefish

#endif  // CUTTLEFISH_COMMON_COMMON_LIBS_FS_SHARED_FD_H_
