// Copyright 2014 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 "fake_ppapi/fake_messaging_interface.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 {

// Helper function for calling ki_ioctl without having
// to construct a va_list.
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;
}

// Helper function for converting PP_Var to C++ string
std::string VarToString(VarInterface* var_iface, PP_Var var) {
  EXPECT_EQ(PP_VARTYPE_STRING, var.type);
  uint32_t len = 0;
  const char* str = var_iface->VarToUtf8(var, &len);
  return std::string(str, len);
}

PP_Var VarFromCStr(VarInterface* iface, const char* string) {
  return iface->VarFromUtf8(string, strlen(string));
}

// Helper function for creating message in the format expected by jspipe
// nodes: [ name, payload ]
PP_Var CreatePipeMessage(PepperInterface* ppapi, const char* pipe,
                         const char* operation, PP_Var payload) {
  VarInterface* var_iface = ppapi->GetVarInterface();
  VarDictionaryInterface* dict_iface = ppapi->GetVarDictionaryInterface();

  // Create a two element array containing the name of the message
  // as the first element.  Its up to the caller the then set the
  // second array element.
  PP_Var message = dict_iface->Create();
  PP_Var pipe_var = VarFromCStr(var_iface, pipe);
  PP_Var operation_var = VarFromCStr(var_iface, operation);
  PP_Var pipe_key = VarFromCStr(var_iface, "pipe");
  PP_Var payload_key = VarFromCStr(var_iface, "payload");
  PP_Var operation_key = VarFromCStr(var_iface, "operation");
  dict_iface->Set(message, pipe_key, pipe_var);
  dict_iface->Set(message, operation_key, operation_var);
  dict_iface->Set(message, payload_key, payload);
  var_iface->Release(pipe_var);
  var_iface->Release(operation_var);
  var_iface->Release(payload);
  var_iface->Release(pipe_key);
  var_iface->Release(payload_key);
  var_iface->Release(operation_key);
  return message;
}

// Helper function for creating "ack" message in format expected
// by jspipe nodes.
PP_Var CreateAckMessage(PepperInterface* ppapi, const char* pipe,
                        int32_t count) {
  return CreatePipeMessage(ppapi, pipe, "ack", PP_MakeInt32(count));
}

// Helper function for creating "write" message in format expected
// by jspipe nodes.
PP_Var CreateWriteMessage(PepperInterface* ppapi,
                          const char* pipe,
                          const char* string,
                          int length=-1) {
  VarArrayBufferInterface* buffer_iface = ppapi->GetVarArrayBufferInterface();

  if (length == -1)
    length = strlen(string);

  PP_Var buffer = buffer_iface->Create(length);
  memcpy(buffer_iface->Map(buffer), string, length);
  buffer_iface->Unmap(buffer);

  return CreatePipeMessage(ppapi, pipe, "write", buffer);
}

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

  void TearDown() {
    ki_uninit();
  }

 protected:
  FakePepperInterface ppapi_;
  KernelProxy kp_;
};

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

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

  /**
   * Create a PP_Var message in the same way that we expect
   * JavaScript code to, and send it to the pipe using ioctl()
   */
  int JSPipeInject(const char* string, int length=-1) {
    PP_Var message = CreateWriteMessage(&ppapi_, name_, string, length);

    // Send the message via ioctl
    int rtn = pipe_dev_->Ioctl(NACL_IOC_HANDLEMESSAGE, &message);

    // Release message
    ppapi_.GetVarInterface()->Release(message);
    return rtn;
  }

  int JSPipeInjectAck(int32_t count) {
    PP_Var message = CreateAckMessage(&ppapi_, name_, count);

    // Send the message via ioctl
    int rtn = pipe_dev_->Ioctl(NACL_IOC_HANDLEMESSAGE, &message);

    // Release message
    ppapi_.GetVarInterface()->Release(message);
    return rtn;
  }

  // Verify the contents of the jspipe mesage, which should be
  // {
  //   "pipe": '<pipe_name>',
  //   "operation": '<command_name>',
  //   "payload": payload
  // }
  void VerifyPipeMessage(PP_Var message,
                         const char* pipe_name,
                         const char* operation,
                         const char* payload,
                         int payload_length,
                         int32_t int_payload=0) {
    VarArrayInterface* array_iface = ppapi_.GetVarArrayInterface();
    VarDictionaryInterface* dict_iface = ppapi_.GetVarDictionaryInterface();
    VarInterface* var_iface = ppapi_.GetVarInterface();
    VarArrayBufferInterface* buffer_iface = ppapi_.GetVarArrayBufferInterface();

    // Verify we have a dictionary with 3 keys
    ASSERT_EQ(PP_VARTYPE_DICTIONARY, message.type);
    PP_Var keys = dict_iface->GetKeys(message);
    ASSERT_EQ(PP_VARTYPE_ARRAY, keys.type);
    ASSERT_EQ(3, array_iface->GetLength(keys));
    var_iface->Release(keys);

    // Verify the keys
    PP_Var key1 = VarFromCStr(var_iface, "pipe");
    PP_Var key2 = VarFromCStr(var_iface, "operation");
    PP_Var key3 = VarFromCStr(var_iface, "payload");

    // Verify pipe name and operation values
    PP_Var value1 = dict_iface->Get(message, key1);
    ASSERT_STREQ(pipe_name, VarToString(var_iface, value1).c_str());
    var_iface->Release(value1);
    var_iface->Release(key1);

    PP_Var value2 = dict_iface->Get(message, key2);
    ASSERT_STREQ(operation, VarToString(var_iface, value2).c_str());
    var_iface->Release(value2);
    var_iface->Release(key2);

    // Verify the payload
    PP_Var payload_var = dict_iface->Get(message, key3);
    if (payload != NULL) {
      ASSERT_EQ(PP_VARTYPE_ARRAY_BUFFER, payload_var.type);
      ASSERT_EQ(0, memcmp(payload, buffer_iface->Map(payload_var),
                          payload_length));
    } else {
      ASSERT_EQ(PP_VARTYPE_INT32, payload_var.type);
      ASSERT_EQ(int_payload, payload_var.value.as_int);
    }
    var_iface->Release(key3);
    var_iface->Release(payload_var);
  }

 protected:
  FakePepperInterface ppapi_;
  DevFsForTesting fs_;
  ScopedNode pipe_dev_;
  const char* name_;
};

TEST(JSPipeTestBasic, MissingPepper) {
  // Create a devfs filesystem without giving it any Pepper implemenation.
  TypedFsFactory<DevFs> factory;
  ScopedFilesystem fs;
  FsInitArgs args(1);
  factory.CreateFilesystem(args, &fs);
  ScopedNode pipe_dev;
  ASSERT_EQ(0, fs->Open(Path("/jspipe1"), O_RDWR, &pipe_dev));

  // Writing to a pipe should return EIO because Pepper is missing.
  HandleAttr attrs;
  int written = -1;
  ASSERT_EQ(EIO, pipe_dev->Write(attrs, "test", 4, &written));
}

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

TEST_F(JSPipeNodeTest, JSPipeInput) {
  std::string message("hello, how are you?\n");

  // First we send some data into the pipe.  This is how messages
  // from javascript are injected into the pipe nodes.
  ASSERT_EQ(0, JSPipeInject(message.c_str()));

  // 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', sizeof(buffer));
  memset(backup_buffer, 'a', sizeof(backup_buffer));

  // We read a small chunk first to ensure it doesn't give us
  // more than we ask for.
  HandleAttr attrs;
  ASSERT_EQ(0, pipe_dev_->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, sizeof(buffer)-5));

  // Now we ask for more data than is left in the pipe, to ensure
  // it doesn't give us more than there is.
  ASSERT_EQ(0, pipe_dev_->Read(attrs, buffer + 5, sizeof(buffer)-5,
                               &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()));
}

TEST_F(JSPipeNodeTest, JSPipeOutput) {
  std::string message("hello");

  int bytes_written = 999;
  HandleAttr attrs;
  ASSERT_EQ(0, pipe_dev_->Write(attrs, message.c_str(), message.size(),
                                &bytes_written));
  ASSERT_EQ(message.size(), bytes_written);

  FakeMessagingInterface* iface =
      (FakeMessagingInterface*)ppapi_.GetMessagingInterface();

  // Verify that exactly one message sent.
  ASSERT_EQ(1, iface->messages.size());
  PP_Var message_var = iface->messages[0];

  // Verify the content of the message.
  VerifyPipeMessage(message_var, "jspipe1", "write", message.c_str(),
                    message.size());
}

TEST_F(JSPipeNodeTest, JSPipeOutputWithNulls) {
  char message[20];
  int message_len = sizeof(message);

  // Construct a 20-byte  message containing the string 'hello' but with
  // null chars on either end.
  memset(message, 0 , message_len);
  memcpy(message+10, "hello", 5);

  int bytes_written = 999;
  HandleAttr attrs;
  EXPECT_EQ(0, pipe_dev_->Write(attrs, message, message_len, &bytes_written));
  EXPECT_EQ(message_len, bytes_written);

  // Verify that the correct messages was sent via PostMessage.
  FakeMessagingInterface* iface =
      (FakeMessagingInterface*)ppapi_.GetMessagingInterface();

  // Verify that exaclty one message sent.
  ASSERT_EQ(1, iface->messages.size());
  PP_Var message_var = iface->messages[0];

  // Verify the content of the message.
  VerifyPipeMessage(message_var, "jspipe1", "write", message, message_len);
}

#define CHUNK_SIZE 678
TEST_F(JSPipeNodeTest, JSPipeOutputBuffer) {
  int ospace_orig = -1;
  ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETOSPACE, &ospace_orig));
  ASSERT_GT(ospace_orig, 0);

  HandleAttr attrs;
  attrs.flags = O_NONBLOCK;
  char* message = (char*)malloc(CHUNK_SIZE);

  // Keep writing data until we block.
  int total_written = 0;
  while (1) {
    int bytes_written;
    // Write some data
    int rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
    if (rtn != 0) {
      ASSERT_EQ(EWOULDBLOCK, rtn);
      int ospace = -1;
      ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETOSPACE, &ospace));
      ASSERT_EQ(0, ospace);
      ASSERT_EQ(total_written, ospace_orig);
      break;
    }
    total_written += bytes_written;
  }

  // At this point writes should always block
  int bytes_written;
  int rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
  ASSERT_EQ(EWOULDBLOCK, rtn);

  // Now inject and ACK message from JavaScript.
  ASSERT_EQ(0, JSPipeInjectAck(10));

  // Now it should be possible to write 10 bytes to the pipe.
  rtn = pipe_dev_->Write(attrs, message, CHUNK_SIZE, &bytes_written);
  ASSERT_EQ(0, rtn);
  ASSERT_EQ(10, bytes_written);

  free(message);
}

TEST_F(JSPipeNodeTest, JSPipeInputBuffer) {
  char* message = (char*)malloc(CHUNK_SIZE);
  memset(message, 1, CHUNK_SIZE);

  int ispace_orig = -1;
  ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETISPACE, &ispace_orig));

  // Keep injecting data until the ioctl fails
  int total_written = 0;
  while (1) {
    int rtn = JSPipeInject(message, CHUNK_SIZE);
    if (rtn != 0) {
      ASSERT_LT(total_written, ispace_orig);
      ASSERT_GT(total_written, ispace_orig - CHUNK_SIZE - 1);
      break;
    }
    total_written += CHUNK_SIZE;
  }

  int ispace = -1;
  ASSERT_EQ(0, pipe_dev_->Ioctl(NACL_IOC_PIPE_GETISPACE, &ispace));
  ASSERT_EQ(0, ispace);

  // Check that no messages have thus far been sent to JavaScript
  FakeMessagingInterface* iface =
      (FakeMessagingInterface*)ppapi_.GetMessagingInterface();
  ASSERT_EQ(0, iface->messages.size());

  // Read some data from the pipe, which should trigger an ack message
  int bytes_read = -1;
  HandleAttr attrs;
  ASSERT_EQ(0, pipe_dev_->Read(attrs, message, 5, &bytes_read));
  ASSERT_EQ(5, bytes_read);

  // Verify that an ack was sent to JavaScript
  ASSERT_EQ(1, iface->messages.size());
  PP_Var message_var = iface->messages[0];
  VerifyPipeMessage(message_var, "jspipe1", "ack", NULL, 0, 5);

  free(message);
}

// Returns:
//   0 -> Not readable
//   1 -> Readable
//  -1 -> Error occured
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(JSPipeTest, JSPipeSelect) {
  struct timeval timeout;
  fd_set readfds;
  fd_set writefds;
  fd_set errorfds;

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

  FD_ZERO(&readfds);
  FD_ZERO(&errorfds);
  FD_SET(pipe_fd, &readfds);
  FD_SET(pipe_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(pipe_fd + 1, &readfds, NULL, &errorfds, &timeout);
  ASSERT_EQ(0, rtn) << "select failed: " << rtn << " err=" << strerror(errno);
  ASSERT_FALSE(FD_ISSET(pipe_fd, &readfds));
  ASSERT_FALSE(FD_ISSET(pipe_fd, &errorfds));

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

  // Send 4 bytes to the pipe via ioctl
  PP_Var message = CreateWriteMessage(&ppapi_, "jspipe1", "test");
  ASSERT_EQ(0, ki_ioctl_wrapper(pipe_fd, NACL_IOC_HANDLEMESSAGE, &message));
  ppapi_.GetVarInterface()->Release(message);

  // Pipe should now be readable
  ASSERT_EQ(1, IsReadable(pipe_fd));

  ki_close(pipe_fd);
}

}
