#include "aos/events/epoll.h"

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

#include "glog/logging.h"
#include "gtest/gtest.h"

namespace aos {
namespace internal {
namespace testing {

// A simple wrapper around both ends of a pipe along with some helpers to easily
// read/write data through it.
class Pipe {
 public:
  Pipe() { PCHECK(pipe2(fds_, O_NONBLOCK) == 0); }
  ~Pipe() {
    if (fds_[0] >= 0) {
      PCHECK(close(fds_[0]) == 0);
    }
    if (fds_[1] >= 0) {
      PCHECK(close(fds_[1]) == 0);
    }
  }

  int read_fd() { return fds_[0]; }
  int write_fd() { return fds_[1]; }
  void close_read_fd() {
    PCHECK(close(fds_[0]) == 0);
    fds_[0] = -1;
  }

  void Write(const std::string &data) {
    CHECK_EQ(write(write_fd(), data.data(), data.size()),
             static_cast<ssize_t>(data.size()));
  }

  std::string Read(size_t size) {
    std::string result;
    result.resize(size);
    CHECK_EQ(read(read_fd(), result.data(), size), static_cast<ssize_t>(size));
    return result;
  }

 private:
  int fds_[2];
};

class EPollTest : public ::testing::Test {
 public:
  void RunFor(std::chrono::nanoseconds duration) {
    TimerFd timerfd;
    bool did_quit = false;
    epoll_.OnReadable(timerfd.fd(), [this, &timerfd, &did_quit]() {
      CHECK(!did_quit);
      epoll_.Quit();
      did_quit = true;
      timerfd.Read();
    });
    timerfd.SetTime(monotonic_clock::now() + duration,
                    monotonic_clock::duration::zero());
    epoll_.Run();
    CHECK(did_quit);
    epoll_.DeleteFd(timerfd.fd());
  }

  // Tests should avoid relying on ordering for events closer in time than this,
  // or waiting for longer than this to ensure events happen in order.
  static constexpr std::chrono::nanoseconds tick_duration() {
    return std::chrono::milliseconds(50);
  }

  EPoll epoll_;
};

// Test that the basics of OnReadable work.
TEST_F(EPollTest, BasicReadable) {
  Pipe pipe;
  bool got_data = false;
  epoll_.OnReadable(pipe.read_fd(), [&]() {
    ASSERT_FALSE(got_data);
    ASSERT_EQ("some", pipe.Read(4));
    got_data = true;
  });
  RunFor(tick_duration());
  EXPECT_FALSE(got_data);

  pipe.Write("some");
  RunFor(tick_duration());
  EXPECT_TRUE(got_data);

  epoll_.DeleteFd(pipe.read_fd());
}

// Test that the basics of OnWriteable work.
TEST_F(EPollTest, BasicWriteable) {
  Pipe pipe;
  int number_writes = 0;
  epoll_.OnWriteable(pipe.write_fd(), [&]() {
    pipe.Write(" ");
    ++number_writes;
  });

  // First, fill up the pipe's write buffer.
  RunFor(tick_duration());
  EXPECT_GT(number_writes, 0);

  // Now, if we try again, we shouldn't do anything.
  const int bytes_in_pipe = number_writes;
  number_writes = 0;
  RunFor(tick_duration());
  EXPECT_EQ(number_writes, 0);

  // Empty the pipe, then fill it up again.
  for (int i = 0; i < bytes_in_pipe; ++i) {
    ASSERT_EQ(" ", pipe.Read(1));
  }
  number_writes = 0;
  RunFor(tick_duration());
  EXPECT_EQ(number_writes, bytes_in_pipe);

  epoll_.DeleteFd(pipe.write_fd());
}

// Test that the basics of OnError work.
TEST_F(EPollTest, BasicError) {
  // In order to trigger an error, close the read file descriptor (per the
  // epoll_ctl manpage, this should trigger an error).
  Pipe pipe;
  int number_errors = 0;
  epoll_.OnError(pipe.write_fd(), [&]() {
    ++number_errors;
  });

  // Sanity check that we *don't* get any errors before anything interesting has
  // happened.
  RunFor(tick_duration());
  EXPECT_EQ(number_errors, 0);

  pipe.close_read_fd();

  // For some reason, OnError doesn't seem to play nice with the timer setup we
  // have in this test, so just poll for a single event.
  epoll_.Poll(false);

  EXPECT_EQ(number_errors, 1);

  epoll_.DeleteFd(pipe.write_fd());
}

TEST(EPollDeathTest, InvalidFd) {
  EPoll epoll;
  Pipe pipe;
  epoll.OnReadable(pipe.read_fd(), []() {});
  EXPECT_DEATH(epoll.OnReadable(pipe.read_fd(), []() {}),
               "Duplicate in functions");
  epoll.OnWriteable(pipe.read_fd(), []() {});
  EXPECT_DEATH(epoll.OnWriteable(pipe.read_fd(), []() {}),
               "Duplicate out functions");

  epoll.DeleteFd(pipe.read_fd());
  EXPECT_DEATH(epoll.DeleteFd(pipe.read_fd()), "fd [0-9]+ not found");
  EXPECT_DEATH(epoll.DeleteFd(pipe.write_fd()), "fd [0-9]+ not found");
}

// Tests that enabling/disabling a writeable FD works.
TEST_F(EPollTest, WriteableEnableDisable) {
  Pipe pipe;
  int number_writes = 0;
  epoll_.OnWriteable(pipe.write_fd(), [&]() {
    pipe.Write(" ");
    ++number_writes;
  });

  // First, fill up the pipe's write buffer.
  RunFor(tick_duration());
  EXPECT_GT(number_writes, 0);

  // Empty the pipe.
  const int bytes_in_pipe = number_writes;
  for (int i = 0; i < bytes_in_pipe; ++i) {
    ASSERT_EQ(" ", pipe.Read(1));
  }

  // If we disable writeable checking, then nothing should happen.
  epoll_.DisableWriteable(pipe.write_fd());
  number_writes = 0;
  RunFor(tick_duration());
  EXPECT_EQ(number_writes, 0);

  // Disabling it again should be a NOP.
  epoll_.DisableWriteable(pipe.write_fd());

  // And then when we re-enable, it should fill the pipe up again.
  epoll_.EnableWriteable(pipe.write_fd());
  number_writes = 0;
  RunFor(tick_duration());
  EXPECT_EQ(number_writes, bytes_in_pipe);

  epoll_.DeleteFd(pipe.write_fd());
}

TEST_F(EPollTest, QuitInBeforeWait) {
  epoll_.BeforeWait([this]() { epoll_.Quit(); });
  epoll_.Run();
}

}  // namespace testing
}  // namespace internal
}  // namespace aos
