// Copyright 2013 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.

#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/select.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <string>

#include "dev_fs_for_testing.h"
#include "gtest/gtest.h"
#include "nacl_io/devfs/dev_fs.h"
#include "nacl_io/filesystem.h"
#include "nacl_io/ioctl.h"
#include "nacl_io/kernel_intercept.h"
#include "nacl_io/kernel_proxy.h"
#include "nacl_io/osdirent.h"

using namespace nacl_io;

namespace {

static int ki_ioctl_wrapper(int fd, int request, ...) {
  va_list ap;
  va_start(ap, request);
  int rtn = ki_ioctl(fd, request, ap);
  va_end(ap);
  return rtn;
}

static int ki_fcntl_wrapper(int fd, int request, ...) {
  va_list ap;
  va_start(ap, request);
  int rtn = ki_fcntl(fd, request, ap);
  va_end(ap);
  return rtn;
}

static void SetNonBlocking(int fd) {
  int flags = ki_fcntl_wrapper(fd, F_GETFL);
  ASSERT_NE(-1, flags);
  flags |= O_NONBLOCK;
  ASSERT_EQ(0, ki_fcntl_wrapper(fd, F_SETFL, flags));
  ASSERT_EQ(flags, ki_fcntl_wrapper(fd, F_GETFL));
}

class TtyNodeTest : public ::testing::Test {
 public:
  TtyNodeTest() : fs_(&ppapi_) {}

  void SetUp() {
    ASSERT_EQ(0, fs_.Open(Path("/tty"), O_RDWR, &dev_tty_));
    ASSERT_NE(NULL_NODE, dev_tty_.get());
    struct stat buf;
    ASSERT_EQ(0, dev_tty_->GetStat(&buf));
    ASSERT_EQ(S_IRUSR | S_IWUSR, buf.st_mode & S_IRWXU);
  }

 protected:
  FakePepperInterface ppapi_;
  DevFsForTesting fs_;
  ScopedNode dev_tty_;
};

class TtyTest : public ::testing::Test {
 public:
  void SetUp() {
    ASSERT_EQ(0, ki_push_state_for_testing());
    ASSERT_EQ(0, ki_init_interface(&kp_, &ppapi_));

    var_iface_ = ppapi_.GetVarInterface();
  }

  void TearDown() {
    ki_uninit();
  }

  int TtyWrite(int fd, const char* string) {
    PP_Var message_var = var_iface_->VarFromUtf8(string, strlen(string));
    int result = ki_ioctl_wrapper(fd, NACL_IOC_HANDLEMESSAGE, &message_var);
    var_iface_->Release(message_var);
    return result;
  }

 protected:
  FakePepperInterface ppapi_;
  KernelProxy kp_;
  VarInterface* var_iface_;
};

TEST_F(TtyNodeTest, InvalidIoctl) {
  // 123 is not a valid ioctl request.
  EXPECT_EQ(EINVAL, dev_tty_->Ioctl(123));
}

TEST_F(TtyNodeTest, TtyInput) {
  // Now let's try sending some data over.
  // First we create the message.
  std::string message("hello, how are you?\n");
  VarInterface* var_iface = ppapi_.GetVarInterface();
  PP_Var message_var = var_iface->VarFromUtf8(message.data(), message.size());

  // Now we make buffer we'll read into.
  // We fill the buffer and a backup buffer with arbitrary data
  // and compare them after reading to make sure read doesn't
  // clobber parts of the buffer it shouldn't.
  int bytes_read;
  char buffer[100];
  char backup_buffer[100];
  memset(buffer, 'a', 100);
  memset(backup_buffer, 'a', 100);

  // Now we actually send the data
  EXPECT_EQ(0, dev_tty_->Ioctl(NACL_IOC_HANDLEMESSAGE, &message_var));

  var_iface->Release(message_var);

  // We read a small chunk first to ensure it doesn't give us
  // more than we ask for.
  HandleAttr attrs;
  EXPECT_EQ(0, dev_tty_->Read(attrs, buffer, 5, &bytes_read));
  EXPECT_EQ(5, bytes_read);
  EXPECT_EQ(0, memcmp(message.data(), buffer, 5));
  EXPECT_EQ(0, memcmp(buffer + 5, backup_buffer + 5, 95));

  // Now we ask for more data than is left in the tty, to ensure
  // it doesn't give us more than is there.
  EXPECT_EQ(0, dev_tty_->Read(attrs, buffer + 5, 95, &bytes_read));
  EXPECT_EQ(bytes_read, message.size() - 5);
  EXPECT_EQ(0, memcmp(message.data(), buffer, message.size()));
  EXPECT_EQ(0, memcmp(buffer + message.size(),
                      backup_buffer + message.size(),
                      100 - message.size()));
}

struct user_data_t {
  const char* output_buf;
  size_t output_count;
};

static ssize_t output_handler(const char* buf, size_t count, void* data) {
  user_data_t* user_data = static_cast<user_data_t*>(data);
  user_data->output_buf = buf;
  user_data->output_count = count;
  return count;
}

TEST_F(TtyNodeTest, TtyOutput) {
  // When no handler is registered then all writes should return EIO
  int bytes_written = 10;
  const char* message = "hello\n";
  int message_len = strlen(message);
  HandleAttr attrs;
  EXPECT_EQ(EIO, dev_tty_->Write(attrs, message, message_len, &bytes_written));

  // Setup output handler with user_data to record calls.
  user_data_t user_data;
  user_data.output_buf = NULL;
  user_data.output_count = 0;

  tioc_nacl_output handler;
  handler.handler = output_handler;
  handler.user_data = &user_data;

  EXPECT_EQ(0, dev_tty_->Ioctl(TIOCNACLOUTPUT, &handler));

  EXPECT_EQ(0, dev_tty_->Write(attrs, message, message_len, &bytes_written));
  EXPECT_EQ(message_len, bytes_written);
  EXPECT_EQ(message_len, user_data.output_count);
  EXPECT_EQ(0, strncmp(user_data.output_buf, message, message_len));
}

// Returns:
//   0 -> Not readable
//   1 -> Readable
//  -1 -> Error occured
static int IsReadable(int fd) {
  struct timeval timeout = {0, 0};
  fd_set readfds;
  fd_set errorfds;
  FD_ZERO(&readfds);
  FD_ZERO(&errorfds);
  FD_SET(fd, &readfds);
  FD_SET(fd, &errorfds);
  int rtn = ki_select(fd + 1, &readfds, NULL, &errorfds, &timeout);
  if (rtn == 0)
    return 0;  // not readable
  if (rtn != 1)
    return -1;  // error
  if (FD_ISSET(fd, &errorfds))
    return -2;  // error
  if (!FD_ISSET(fd, &readfds))
    return -3;  // error
  return 1;     // readable
}

TEST_F(TtyTest, TtySelect) {
  struct timeval timeout;
  fd_set readfds;
  fd_set writefds;
  fd_set errorfds;

  int tty_fd = ki_open("/dev/tty", O_RDONLY, 0);
  ASSERT_GT(tty_fd, 0) << "tty open failed: " << errno;

  FD_ZERO(&readfds);
  FD_ZERO(&errorfds);
  FD_SET(tty_fd, &readfds);
  FD_SET(tty_fd, &errorfds);
  // 10 millisecond timeout
  timeout.tv_sec = 0;
  timeout.tv_usec = 10 * 1000;
  // Should timeout when no input is available.
  int rtn = ki_select(tty_fd + 1, &readfds, NULL, &errorfds, &timeout);
  ASSERT_EQ(0, rtn) << "select failed: " << rtn << " err=" << strerror(errno);
  ASSERT_FALSE(FD_ISSET(tty_fd, &readfds));
  ASSERT_FALSE(FD_ISSET(tty_fd, &errorfds));

  FD_ZERO(&readfds);
  FD_ZERO(&writefds);
  FD_ZERO(&errorfds);
  FD_SET(tty_fd, &readfds);
  FD_SET(tty_fd, &writefds);
  FD_SET(tty_fd, &errorfds);
  // TTY should be writable on startup.
  rtn = ki_select(tty_fd + 1, &readfds, &writefds, &errorfds, NULL);
  ASSERT_EQ(1, rtn);
  ASSERT_TRUE(FD_ISSET(tty_fd, &writefds));
  ASSERT_FALSE(FD_ISSET(tty_fd, &readfds));
  ASSERT_FALSE(FD_ISSET(tty_fd, &errorfds));

  // Send 4 bytes to TTY input
  ASSERT_EQ(0, TtyWrite(tty_fd, "input:test"));

  // TTY should not be readable until newline in written
  ASSERT_EQ(IsReadable(tty_fd), 0);
  ASSERT_EQ(0, TtyWrite(tty_fd, "input:\n"));

  // TTY should now be readable
  ASSERT_EQ(1, IsReadable(tty_fd));

  ASSERT_EQ(0, ki_close(tty_fd));
}

TEST_F(TtyTest, TtyICANON) {
  int tty_fd = ki_open("/dev/tty", O_RDONLY, 0);

  ASSERT_EQ(0, IsReadable(tty_fd));

  struct termios tattr;
  ki_tcgetattr(tty_fd, &tattr);
  tattr.c_lflag &= ~(ICANON | ECHO); /* Clear ICANON and ECHO. */
  ki_tcsetattr(tty_fd, TCSAFLUSH, &tattr);

  ASSERT_EQ(0, IsReadable(tty_fd));

  // Set some bytes to the TTY, not including newline
  ASSERT_EQ(0, TtyWrite(tty_fd, "a"));

  // Since we are not in canonical mode the bytes should be
  // immediately readable.
  ASSERT_EQ(1, IsReadable(tty_fd));

  // Read byte from tty.
  char c;
  ASSERT_EQ(1, ki_read(tty_fd, &c, 1));
  ASSERT_EQ('a', c);

  ASSERT_EQ(0, IsReadable(tty_fd));
}

static int g_received_signal;

static void sighandler(int sig) { g_received_signal = sig; }

TEST_F(TtyTest, WindowSize) {
  // Get current window size
  struct winsize old_winsize = {0};
  int tty_fd = ki_open("/dev/tty", O_RDONLY, 0);
  ASSERT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCGWINSZ, &old_winsize));

  // Install signal handler
  sighandler_t new_handler = sighandler;
  sighandler_t old_handler = ki_signal(SIGWINCH, new_handler);
  ASSERT_NE(SIG_ERR, old_handler) << "signal return error: " << errno;

  g_received_signal = 0;

  // Set a new windows size
  struct winsize winsize;
  winsize.ws_col = 100;
  winsize.ws_row = 200;
  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCSWINSZ, &winsize));
  EXPECT_EQ(SIGWINCH, g_received_signal);

  // Restore old signal handler
  EXPECT_EQ(new_handler, ki_signal(SIGWINCH, old_handler));

  // Verify new window size can be queried correctly.
  winsize.ws_col = 0;
  winsize.ws_row = 0;
  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCGWINSZ, &winsize));
  EXPECT_EQ(100, winsize.ws_col);
  EXPECT_EQ(200, winsize.ws_row);

  // Restore original windows size.
  EXPECT_EQ(0, ki_ioctl_wrapper(tty_fd, TIOCSWINSZ, &old_winsize));
}

/*
 * Sleep for 50ms then send a resize event to /dev/tty.
 */
static void* resize_thread_main(void* arg) {
  usleep(50 * 1000);

  int* tty_fd = static_cast<int*>(arg);
  struct winsize winsize;
  winsize.ws_col = 100;
  winsize.ws_row = 200;
  ki_ioctl_wrapper(*tty_fd, TIOCSWINSZ, &winsize);
  return NULL;
}

TEST_F(TtyTest, ResizeDuringSelect) {
  // Test that a window resize during a call
  // to select(3) will cause it to fail with EINTR.
  int tty_fd = ki_open("/dev/tty", O_RDONLY, 0);

  fd_set readfds;
  fd_set errorfds;
  FD_ZERO(&readfds);
  FD_ZERO(&errorfds);
  FD_SET(tty_fd, &readfds);
  FD_SET(tty_fd, &errorfds);

  pthread_t resize_thread;
  pthread_create(&resize_thread, NULL, resize_thread_main, &tty_fd);

  struct timeval timeout;
  timeout.tv_sec = 20;
  timeout.tv_usec = 0;

  // TTY should not be readable either before or after the
  // call to select(3).
  ASSERT_EQ(0, IsReadable(tty_fd));

  int rtn = ki_select(tty_fd + 1, &readfds, NULL, &errorfds, &timeout);
  pthread_join(resize_thread, NULL);
  ASSERT_EQ(-1, rtn);
  ASSERT_EQ(EINTR, errno);
  ASSERT_EQ(0, IsReadable(tty_fd));
}

/*
 * Sleep for 50ms then send some input to the /dev/tty.
 */
static void* input_thread_main(void* arg) {
  TtyTest* thiz = static_cast<TtyTest*>(arg);

  usleep(50 * 1000);

  int fd = ki_open("/dev/tty", O_RDONLY, 0);
  thiz->TtyWrite(fd, "test\n");
  return NULL;
}

TEST_F(TtyTest, InputDuringSelect) {
  // Test that input which occurs while in select causes
  // select to return.
  int tty_fd = ki_open("/dev/tty", O_RDONLY, 0);

  fd_set readfds;
  fd_set errorfds;
  FD_ZERO(&readfds);
  FD_ZERO(&errorfds);
  FD_SET(tty_fd, &readfds);
  FD_SET(tty_fd, &errorfds);

  pthread_t resize_thread;
  pthread_create(&resize_thread, NULL, input_thread_main, this);

  struct timeval timeout;
  timeout.tv_sec = 20;
  timeout.tv_usec = 0;

  int rtn = ki_select(tty_fd + 1, &readfds, NULL, &errorfds, &timeout);
  pthread_join(resize_thread, NULL);

  ASSERT_EQ(1, rtn);
}

TEST_F(TtyTest, NonBlocking) {
  // Test that non-blocking mode works.
  int fd = ki_open("/dev/tty", O_RDONLY, 0);
  ASSERT_GT(fd, 0) << "tty open failed: " << errno;
  SetNonBlocking(fd);
  int bytes_read;
  char buffer[100];
  bytes_read = ki_read(fd, buffer, sizeof(buffer));
  ASSERT_EQ(-1, bytes_read);
  ASSERT_EQ(EWOULDBLOCK, errno);
  ASSERT_EQ(0, TtyWrite(fd, "test\n"));
  bytes_read = ki_read(fd, buffer, sizeof(buffer));
  ASSERT_EQ(5, bytes_read);
  ASSERT_EQ(0, memcmp(buffer, "test\n", 5));
}

}  // namespace
