// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <netdb.h>
#include <pthread.h>
#include <pwd.h>
#include <stdarg.h>
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <termios.h>

#include "nacl-mounts/base/irt_syscalls.h"

#include "file_system.h"

extern "C" {

#define WRAP(name) __user_irt_##name
#define REAL(name) libnacl_##name

/*
 * Wrapped functions will return 0/errno on success, and pass back the real
 * value via an argument.  Shuffle the values around to match standard C lib
 * API where errors are set in errno.
 */
#define HANDLE_ERRNO(call, success) \
  ({ \
    __typeof(success) ret = (call); \
    if (ret) { \
      errno = ret; \
      ret = -1; \
    } else { \
      ret = (success); \
    } \
    ret; \
  })

void debug_log(const char* format, ...) {
  // This shouldn't be necessary, but can't rely on the underlying C lib
  // not messing with the errno value.
  int saved = errno;
  va_list ap;
  va_start(ap, format);
  vfprintf(stderr, format, ap);
  va_end(ap);
  errno = saved;
}

static bool g_exit_called = false;

static int WRAP(open)(const char* pathname, int oflag, mode_t cmode,
                      int* newfd) {
  LOG("open: %s\n", pathname);
  return FileSystem::GetFileSystem()->open(pathname, oflag, cmode, newfd);
}

#ifndef O_TMPFILE
# define O_TMPFILE 0
#endif
int open(const char* file, int oflag, ...) {
  int newfd;
  mode_t cmode = 0;

  // Only peel off the mode if the call requires it.  Otherwise we enter
  // "undefined" territory and get garbage or a crash or ...
  if (oflag & (O_CREAT | O_TMPFILE)) {
    va_list ap;
    va_start(ap, oflag);
    cmode = va_arg(ap, mode_t);
    va_end(ap);
  }
  return HANDLE_ERRNO(WRAP(open)(file, oflag, cmode, &newfd), newfd);
}

static int WRAP(close)(int fd) {
  LOG("close: %d\n", fd);
  return FileSystem::GetFileSystem()->close(fd);
}

int close(int fd) {
  return HANDLE_ERRNO(WRAP(close)(fd), 0);
}

static int WRAP(read)(int fd, void* buf, size_t count, size_t* nread) {
  VLOG("read: %d %d\n", fd, count);
  return FileSystem::GetFileSystem()->read(fd, (char*)buf, count, nread);
}

ssize_t read(int fd, void* buf, size_t count) {
  ssize_t rv;
  return HANDLE_ERRNO(WRAP(read)(fd, buf, count, (size_t*)&rv), rv);
}

/* TODO(olonho): ugly hack to get access to the real write(). Fortunately,
   NaCl library ABI is pretty stable.*/
#define NACL_IRT_FDIO_v0_1      "nacl-irt-fdio-0.1"
extern struct nacl_irt_fdio __libnacl_irt_fdio;
struct nacl_irt_fdio {
  int (*close)(int fd);
  int (*dup)(int fd, int* newfd);
  int (*dup2)(int fd, int newfd);
  int (*read)(int fd, void* buf, size_t count, size_t* nread);
  int (*write)(int fd, const void* buf, size_t count, size_t* nwrote);
  int (*seek)(int fd, off_t offset, int whence, off_t* new_offset);
  int (*fstat)(int fd, struct stat* );
};

int libnacl_write(int fd, const void* buf, size_t count, size_t* nwrote) {
  return __libnacl_irt_fdio.write(fd, buf, count, nwrote);
}

static int WRAP(write)(int fd, const void* buf, size_t count, size_t* nwrote) {
  if (fd != 1 && fd != 2)
    VLOG("write: %d %d\n", fd, count);
#ifndef NDEBUG
  // Have debug builds write stdout/stderr to the program's stdout/stderr too.
  // This helps when debugging on Linux systems.  We also pass it back to the
  // JS layer as CrOS doesn't have a way of viewing the program's stdout/stderr.
  if (fd == 1 || fd == 2) {
    REAL(write)(fd, buf, count, nwrote);
  }
#endif
  return FileSystem::GetFileSystem()->write(fd, (const char*)buf, count,
                                            nwrote);
}

ssize_t write(int fd, const void* buf, size_t count) {
  ssize_t rv;
  return HANDLE_ERRNO(WRAP(write)(fd, buf, count, (size_t*)&rv), rv);
}

static int WRAP(seek)(int fd, nacl_abi_off_t offset, int whence,
               nacl_abi_off_t* new_offset) {
  LOG("seek: %d %d %d\n", fd, (int)offset, whence);
  return FileSystem::GetFileSystem()->seek(fd, offset, whence, new_offset);
}

off_t lseek(int fd, off_t offset, int whence) {
  nacl_abi_off_t rv;
  return HANDLE_ERRNO(WRAP(seek)(fd, offset, whence, &rv), rv);
}

static int WRAP(dup)(int fd, int* newfd) {
  LOG("dup: %d\n", fd);
  return FileSystem::GetFileSystem()->dup(fd, newfd);
}

int dup(int oldfd) {
  int rv;
  return HANDLE_ERRNO(WRAP(dup)(oldfd, &rv), rv);
}

static int WRAP(dup2)(int fd, int newfd) {
  LOG("dup2: %d\n", fd);
  return FileSystem::GetFileSystem()->dup2(fd, newfd);
}

int dup2(int oldfd, int newfd) {
  return HANDLE_ERRNO(WRAP(dup2)(oldfd, newfd), newfd);
}

static int WRAP(stat)(const char* pathname, struct nacl_abi_stat* buf) {
  LOG("stat: %s\n", pathname);
  return FileSystem::GetFileSystem()->stat(pathname, buf);
}

static void stat_n2u(struct nacl_abi_stat* nacl_buf, struct stat* buf) {
  buf->st_dev = nacl_buf->nacl_abi_st_dev;
  buf->st_ino = nacl_buf->nacl_abi_st_ino;
  buf->st_mode = nacl_buf->nacl_abi_st_mode;
  buf->st_nlink = nacl_buf->nacl_abi_st_nlink;
  buf->st_uid = nacl_buf->nacl_abi_st_uid;
  buf->st_gid = nacl_buf->nacl_abi_st_gid;
  buf->st_rdev = nacl_buf->nacl_abi_st_rdev;
  buf->st_size = nacl_buf->nacl_abi_st_size;
  buf->st_blksize = nacl_buf->nacl_abi_st_blksize;
  buf->st_blocks = nacl_buf->nacl_abi_st_blocks;
  buf->st_atime = nacl_buf->nacl_abi_st_atime;
  buf->st_mtime = nacl_buf->nacl_abi_st_mtime;
  buf->st_ctime = nacl_buf->nacl_abi_st_ctime;
}

int stat(const char* path, struct stat* buf) {
  struct nacl_abi_stat nacl_buf;
  int rv = WRAP(stat)(path, &nacl_buf);
  if (rv == 0)
    stat_n2u(&nacl_buf, buf);
  return HANDLE_ERRNO(rv, 0);
}

static int WRAP(fstat)(int fd, struct nacl_abi_stat* buf) {
  LOG("fstat: %d\n", fd);
  return FileSystem::GetFileSystem()->fstat(fd, buf);
}

int fstat(int fd, struct stat* buf) {
  struct nacl_abi_stat nacl_buf;
  int rv = WRAP(fstat)(fd, &nacl_buf);
  if (rv == 0)
    stat_n2u(&nacl_buf, buf);
  return HANDLE_ERRNO(rv, 0);
}

int isatty(int fd) {
  LOG("isatty: %d\n", fd);
  return FileSystem::GetFileSystem()->isatty(fd);
}

int fcntl(int fd, int cmd, ...) {
  LOG("fcntl: %d %d\n", fd, cmd);
  va_list ap;
  va_start(ap, cmd);
  int ret = FileSystem::GetFileSystem()->fcntl(fd, cmd, ap);
  va_end(ap);
  return ret;
}

int ioctl(int fd, int request, ...) {
  LOG("ioctl: %d %d\n", fd, request);
  va_list ap;
  va_start(ap, request);
  int ret = FileSystem::GetFileSystem()->ioctl(fd, request, ap);
  va_end(ap);
  return ret;
}

int select(int nfds, fd_set* readfds, fd_set* writefds,
           fd_set* exceptfds, struct timeval* timeout) {
  VLOG("select: %d\n", nfds);
  return FileSystem::GetFileSystem()->select(nfds, readfds, writefds, exceptfds,
                                             timeout);
}

//------------------------------------------------------------------------------

// Wrap exit and _exit so JavaScript gets our exit code. We don't wrap
// abort so that we have something to chain to, but abort has no exit
// code to report anyway.
void exit(int status) {
  LOG("exit: %d\n", status);
  g_exit_called = true;
  FileSystem::GetFileSystem()->exit(status);
  abort();  // Can we chain to the real exit?
}

void _exit(int status) {
  LOG("_exit: %d\n", status);
  if (g_exit_called) {
    // Infinity exit loop detected. It happens in case of NewLib when abort
    // calls exit inside. The only thing we can do is to stop this thread.
    pthread_exit(NULL);
  }
  g_exit_called = true;
  FileSystem::GetFileSystem()->exit(status);
  abort();  // Can we chain to the real _exit?
}

int seteuid(uid_t euid) {
  LOG("seteuid: %d\n", euid);
  return 0;
}

int setresgid(gid_t rgid, gid_t egid, gid_t sgid) {
  LOG("setresgid: %d %d %d\n", rgid, egid, sgid);
  return 0;
}

int setresuid(uid_t ruid, uid_t euid, uid_t suid) {
  LOG("setresuid: %d %d %d\n", ruid, euid, suid);
  return 0;
}

// We disable the threadsafe lint func here because it applies to the standard
// C library versions, not our stub one here that is actually safe.
struct passwd* getpwuid(uid_t uid) {  // NOLINT(runtime/threadsafe_fn)
  LOG("getpwuid: %d\n", uid);
  static struct passwd pwd;
  pwd.pw_name = (char*)"";
  pwd.pw_passwd = (char*)"";
  pwd.pw_uid = 0;
  pwd.pw_gid = 0;
  pwd.pw_gecos = (char*)"";
  pwd.pw_dir = (char*)"";
  pwd.pw_shell = (char*)"";
  return &pwd;
}

int gethostname(char* name, size_t len) {
  const char* kHostname = "localhost";
  strncpy(name, kHostname, len);
  return 0;
}

int getaddrinfo(const char* hostname, const char* servname,
                const struct addrinfo* hints, struct addrinfo** res) {
  LOG("getaddrinfo: %s %s\n",
      hostname ? hostname : "", servname ? servname : "");
  return FileSystem::GetFileSystem()->getaddrinfo(
      hostname, servname, hints, res);
}

void freeaddrinfo(struct addrinfo* ai) {
  LOG("freeaddrinfo\n");
  return FileSystem::GetFileSystem()->freeaddrinfo(ai);
}

int getnameinfo(const struct sockaddr* sa, socklen_t salen,
                char* host, socklen_t hostlen,
                char* serv, socklen_t servlen, unsigned int flags) {
  LOG("getnameinfo\n");
  return FileSystem::GetFileSystem()->getnameinfo(
      sa, salen, host, hostlen, serv, servlen, flags);
}

int socket(int socket_family, int socket_type, int protocol) {
  LOG("socket: %d %d %d\n", socket_family, socket_type, protocol);
  return FileSystem::GetFileSystem()->socket(
      socket_family, socket_type, protocol);
}

int connect(int sockfd, const struct sockaddr* serv_addr, socklen_t addrlen) {
  LOG("connect: %d\n", sockfd);
  return FileSystem::GetFileSystem()->connect(sockfd, serv_addr, addrlen);
}

pid_t waitpid(pid_t pid, int* status, int options) {
  LOG("waitpid: %d\n", pid);
  return -1;
}

int accept(int sockfd, struct sockaddr* addr, socklen_t* addrlen) {
  LOG("accept: %d\n", sockfd);
  return FileSystem::GetFileSystem()->accept(sockfd, addr, addrlen);
}

int sigaction(int signum, const struct sigaction* act,
              struct sigaction* oldact) {
  LOG("sigaction: %d\n", signum);
  return FileSystem::GetFileSystem()->sigaction(signum, act, oldact);
}

int kill(pid_t pid, int sig) {
  LOG("kill: %d\n", pid);
  return -1;
}

pid_t fork(void) {
  LOG("fork\n");
  return -1;
}

pid_t getpid(void) {
  LOG("getpid\n");
  return 100;
}

int bind(int sockfd, const struct sockaddr* my_addr, socklen_t addrlen) {
  LOG("bind: %d\n", sockfd);
  return FileSystem::GetFileSystem()->bind(sockfd, my_addr, addrlen);
}

int getpeername(int socket, struct sockaddr* address,
                socklen_t* address_len) {
  LOG("getpeername: %d\n", socket);
  return -1;
}

int getsockname(int s, struct sockaddr* name, socklen_t* namelen) {
  LOG("getsockname: %d\n", s);
  return FileSystem::GetFileSystem()->getsockname(s, name, namelen);
}

int listen(int sockfd, int backlog) {
  LOG("listen: %d %d\n", sockfd, backlog);
  return FileSystem::GetFileSystem()->listen(sockfd, backlog);
}

int setsockopt(int socket, int level, int option_name,
               const void* option_value, socklen_t option_len) {
  LOG("setsockopt: %d %d %d\n", socket, level, option_name);
  return 0;
}

int getsockopt(int socket, int level, int option_name,
               void* option_value, socklen_t* option_len) {
  LOG("getsockopt: %d %d %d\n", socket, level, option_name);
  memset(option_value, 0, *option_len);
  return 0;
}

int shutdown(int s, int how) {
  LOG("shutdown: %d %d\n", s, how);
  return FileSystem::GetFileSystem()->shutdown(s, how);
}

int tcgetattr(int fd, struct termios* termios_p) {
  LOG("tcgetattr: %d\n", fd);
  return FileSystem::GetFileSystem()->tcgetattr(fd, termios_p);
}

int tcsetattr(int fd, int optional_actions, const struct termios* termios_p) {
  LOG("tcsetattr: %d\n", fd);
  return FileSystem::GetFileSystem()->tcsetattr(
      fd, optional_actions, termios_p);
}

int mkdir(const char* pathname, mode_t mode) {
  LOG("mkdir: %s\n", pathname);
  return FileSystem::GetFileSystem()->mkdir(pathname, mode);
}

int sched_setscheduler(pid_t pid, int policy,
                       const struct sched_param* param) {
  LOG("sched_setscheduler: %d %d\n", pid, policy);
  return 0;
}

ssize_t send(int fd, const void* buf, size_t count, int flags) {
  VLOG("send: %d %d\n", fd, count);
  size_t sent = 0;
  int rv = FileSystem::GetFileSystem()->write(fd, (const char*)buf,
                                              count, &sent);
  return HANDLE_ERRNO(rv, sent);
}

ssize_t recv(int fd, void* buf, size_t count, int flags) {
  VLOG("recv: %d %d\n", fd, count);
  size_t recvd = 0;
  int rv = FileSystem::GetFileSystem()->read(fd, (char*)buf, count, &recvd);
  return HANDLE_ERRNO(rv, recvd);
}

ssize_t sendto(int sockfd, const void* buf, size_t len, int flags,
               const struct sockaddr* dest_addr, socklen_t addrlen) {
  LOG("sendto: %d %d %d\n", sockfd, len, flags);
  return FileSystem::GetFileSystem()->sendto(sockfd, (char*)buf, len, flags,
                                             dest_addr, addrlen);
}

ssize_t recvfrom(int socket, void* buffer, size_t len, int flags,
                 struct sockaddr* addr, socklen_t* addrlen) {
  LOG("recvfrom: %d %d %d\n", socket, len, flags);
  return FileSystem::GetFileSystem()->recvfrom(socket, (char*)buffer, len,
                                               flags, addr, addrlen);
}

int socketpair(int domain, int type, int protocol, int socket_vector[2]) {
  LOG("socketpair: %d %d %d [%d, %d]\n",
      domain, type, protocol, socket_vector[0], socket_vector[1]);
  errno = EACCES;
  return -1;
}

int clock_gettime(clockid_t clk_id, struct timespec* tp) {
  LOG("clock_gettime: %d\n", (int)clk_id);
  errno = EINVAL;
  return -1;
}

speed_t cfgetospeed(const struct termios* t) {
  return t->c_ospeed;
}

speed_t cfgetispeed(const struct termios* t) {
  return t->c_ispeed;
}

int cfsetospeed(struct termios* t, speed_t speed) {
  t->c_ospeed = speed;
  return 0;
}

int cfsetispeed(struct termios* t, speed_t speed) {
  t->c_ispeed = speed;
  return 0;
}

}  // extern "C"
