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

// A universal test for all event loops supported by the build of QUICHE in
// question.
//
// This test is very similar to QuicPollEventLoopTest, however, there are some
// notable differences:
//   (1) This test uses the real clock, since the event loop implementation may
//       not support accepting a mock clock.
//   (2) This test covers both level-triggered and edge-triggered event loops.

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

#include "absl/cleanup/cleanup.h"
#include "absl/memory/memory.h"
#include "absl/strings/string_view.h"
#include "quiche/quic/core/io/quic_default_event_loop.h"
#include "quiche/quic/core/io/quic_event_loop.h"
#include "quiche/quic/core/quic_alarm.h"
#include "quiche/quic/core/quic_alarm_factory.h"
#include "quiche/quic/core/quic_default_clock.h"
#include "quiche/quic/core/quic_time.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_test_utils.h"

namespace quic::test {
namespace {

using testing::_;
using testing::AtMost;

MATCHER_P(HasFlagSet, value, "Checks a flag in a bit mask") {
  return (arg & value) != 0;
}

constexpr QuicSocketEventMask kAllEvents =
    kSocketEventReadable | kSocketEventWritable | kSocketEventError;

class MockQuicSocketEventListener : public QuicSocketEventListener {
 public:
  MOCK_METHOD(void, OnSocketEvent,
              (QuicEventLoop* /*event_loop*/, QuicUdpSocketFd /*fd*/,
               QuicSocketEventMask /*events*/),
              (override));
};

class MockDelegate : public QuicAlarm::Delegate {
 public:
  QuicConnectionContext* GetConnectionContext() override { return nullptr; }
  MOCK_METHOD(void, OnAlarm, (), (override));
};

void SetNonBlocking(int fd) {
  QUICHE_CHECK(::fcntl(fd, F_SETFL, ::fcntl(fd, F_GETFL) | O_NONBLOCK) == 0)
      << "Failed to mark FD non-blocking, errno: " << errno;
}

class QuicEventLoopFactoryTest
    : public QuicTestWithParam<QuicEventLoopFactory*> {
 public:
  QuicEventLoopFactoryTest()
      : loop_(GetParam()->Create(&clock_)),
        factory_(loop_->CreateAlarmFactory()) {
    int fds[2];
    int result = ::pipe(fds);
    QUICHE_CHECK(result >= 0) << "Failed to create a pipe, errno: " << errno;
    read_fd_ = fds[0];
    write_fd_ = fds[1];

    SetNonBlocking(read_fd_);
    SetNonBlocking(write_fd_);
  }

  ~QuicEventLoopFactoryTest() {
    close(read_fd_);
    close(write_fd_);
  }

  std::pair<std::unique_ptr<QuicAlarm>, MockDelegate*> CreateAlarm() {
    auto delegate = std::make_unique<testing::StrictMock<MockDelegate>>();
    MockDelegate* delegate_unowned = delegate.get();
    auto alarm = absl::WrapUnique(factory_->CreateAlarm(delegate.release()));
    return std::make_pair(std::move(alarm), delegate_unowned);
  }

  template <typename Condition>
  void RunEventLoopUntil(Condition condition, QuicTime::Delta timeout) {
    const QuicTime end = clock_.Now() + timeout;
    while (!condition() && clock_.Now() < end) {
      loop_->RunEventLoopOnce(end - clock_.Now());
    }
  }

 protected:
  QuicDefaultClock clock_;
  std::unique_ptr<QuicEventLoop> loop_;
  std::unique_ptr<QuicAlarmFactory> factory_;
  int read_fd_;
  int write_fd_;
};

std::string GetTestParamName(
    ::testing::TestParamInfo<QuicEventLoopFactory*> info) {
  return EscapeTestParamName(info.param->GetName());
}

INSTANTIATE_TEST_SUITE_P(QuicEventLoopFactoryTests, QuicEventLoopFactoryTest,
                         ::testing::ValuesIn(GetAllSupportedEventLoops()),
                         GetTestParamName);

TEST_P(QuicEventLoopFactoryTest, NothingHappens) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(read_fd_, kAllEvents, &listener));
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  // Attempt double-registration.
  EXPECT_FALSE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));
  // Expect no further calls.
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(5));
}

TEST_P(QuicEventLoopFactoryTest, RearmWriter) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  if (loop_->SupportsEdgeTriggered()) {
    EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
        .Times(1);
    loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
    loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  } else {
    EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
        .Times(2);
    loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
    ASSERT_TRUE(loop_->RearmSocket(write_fd_, kSocketEventWritable));
    loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  }
}

TEST_P(QuicEventLoopFactoryTest, Readable) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(read_fd_, kAllEvents, &listener));

  ASSERT_EQ(4, write(write_fd_, "test", 4));
  EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  // Expect no further calls.
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
}

// A common pattern: read a limited amount of data from an FD, and expect to
// read the remainder on the next operation.
TEST_P(QuicEventLoopFactoryTest, ArtificialNotifyFromCallback) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(read_fd_, kSocketEventReadable, &listener));

  constexpr absl::string_view kData = "test test test test test test test ";
  constexpr size_t kTimes = kData.size() / 5;
  ASSERT_EQ(kData.size(), write(write_fd_, kData.data(), kData.size()));
  EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable))
      .Times(loop_->SupportsEdgeTriggered() ? (kTimes + 1) : kTimes)
      .WillRepeatedly([&]() {
        char buf[5];
        int read_result = read(read_fd_, buf, sizeof(buf));
        if (read_result > 0) {
          ASSERT_EQ(read_result, 5);
          if (loop_->SupportsEdgeTriggered()) {
            EXPECT_TRUE(
                loop_->ArtificiallyNotifyEvent(read_fd_, kSocketEventReadable));
          } else {
            EXPECT_TRUE(loop_->RearmSocket(read_fd_, kSocketEventReadable));
          }
        } else {
          EXPECT_EQ(errno, EAGAIN);
        }
      });
  for (size_t i = 0; i < kTimes + 2; i++) {
    loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  }
}

TEST_P(QuicEventLoopFactoryTest, WriterUnblocked) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));

  int io_result;
  std::string data(2048, 'a');
  do {
    io_result = write(write_fd_, data.data(), data.size());
  } while (io_result > 0);
  ASSERT_EQ(errno, EAGAIN);

  // Rearm if necessary and expect no immediate calls.
  if (!loop_->SupportsEdgeTriggered()) {
    ASSERT_TRUE(loop_->RearmSocket(write_fd_, kSocketEventWritable));
  }
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));

  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
  do {
    io_result = read(read_fd_, data.data(), data.size());
  } while (io_result > 0);
  ASSERT_EQ(errno, EAGAIN);
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
}

TEST_P(QuicEventLoopFactoryTest, ArtificialEvent) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(read_fd_, kAllEvents, &listener));
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  ASSERT_TRUE(loop_->ArtificiallyNotifyEvent(read_fd_, kSocketEventReadable));

  EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable));
  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
}

TEST_P(QuicEventLoopFactoryTest, Unregister) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));
  ASSERT_TRUE(loop_->UnregisterSocket(write_fd_));

  // Expect nothing to happen.
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));

  EXPECT_FALSE(loop_->UnregisterSocket(write_fd_));
  if (!loop_->SupportsEdgeTriggered()) {
    EXPECT_FALSE(loop_->RearmSocket(write_fd_, kSocketEventWritable));
  }
  EXPECT_FALSE(loop_->ArtificiallyNotifyEvent(write_fd_, kSocketEventWritable));
}

TEST_P(QuicEventLoopFactoryTest, UnregisterInsideEventHandler) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(read_fd_, kAllEvents, &listener));
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  // We are not guaranteed the order in which those events will happen, so we
  // try to accommodate both possibilities.
  int total_called = 0;
  EXPECT_CALL(listener, OnSocketEvent(_, read_fd_, kSocketEventReadable))
      .Times(AtMost(1))
      .WillOnce([&]() {
        ++total_called;
        ASSERT_TRUE(loop_->UnregisterSocket(write_fd_));
      });
  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
      .Times(AtMost(1))
      .WillOnce([&]() {
        ++total_called;
        ASSERT_TRUE(loop_->UnregisterSocket(read_fd_));
      });
  ASSERT_TRUE(loop_->ArtificiallyNotifyEvent(read_fd_, kSocketEventReadable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
  EXPECT_EQ(total_called, 1);
}

TEST_P(QuicEventLoopFactoryTest, UnregisterSelfInsideEventHandler) {
  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(write_fd_, kAllEvents, &listener));

  EXPECT_CALL(listener, OnSocketEvent(_, write_fd_, kSocketEventWritable))
      .WillOnce([&]() { ASSERT_TRUE(loop_->UnregisterSocket(write_fd_)); });
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(1));
}

// Creates a bidirectional socket and tests its behavior when it's both readable
// and writable.
TEST_P(QuicEventLoopFactoryTest, ReadWriteSocket) {
  int sockets[2];
  ASSERT_EQ(socketpair(AF_UNIX, SOCK_STREAM, 0, sockets), 0);
  auto close_sockets = absl::MakeCleanup([&]() {
    close(sockets[0]);
    close(sockets[1]);
  });
  SetNonBlocking(sockets[0]);
  SetNonBlocking(sockets[1]);

  testing::StrictMock<MockQuicSocketEventListener> listener;
  ASSERT_TRUE(loop_->RegisterSocket(sockets[0], kAllEvents, &listener));
  EXPECT_CALL(listener, OnSocketEvent(_, sockets[0], kSocketEventWritable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));

  int io_result;
  std::string data(2048, 'a');
  do {
    io_result = write(sockets[0], data.data(), data.size());
  } while (io_result > 0);
  ASSERT_EQ(errno, EAGAIN);

  if (!loop_->SupportsEdgeTriggered()) {
    ASSERT_TRUE(loop_->RearmSocket(sockets[0], kSocketEventWritable));
  }
  // We are not write-blocked, so this should not notify.
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));

  EXPECT_GT(write(sockets[1], data.data(), data.size()), 0);
  EXPECT_CALL(listener, OnSocketEvent(_, sockets[0], kSocketEventReadable));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));

  do {
    char buffer[2048];
    io_result = read(sockets[1], buffer, sizeof(buffer));
  } while (io_result > 0);
  ASSERT_EQ(errno, EAGAIN);
  // Here, we can receive either "writable" or "readable and writable"
  // notification depending on the backend in question.
  EXPECT_CALL(listener,
              OnSocketEvent(_, sockets[0], HasFlagSet(kSocketEventWritable)));
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(4));
}

TEST_P(QuicEventLoopFactoryTest, AlarmInFuture) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm, delegate] = CreateAlarm();

  alarm->Set(clock_.Now() + kAlarmTimeout);

  bool alarm_called = false;
  EXPECT_CALL(*delegate, OnAlarm()).WillOnce([&]() { alarm_called = true; });
  RunEventLoopUntil([&]() { return alarm_called; },
                    QuicTime::Delta::FromMilliseconds(100));
}

TEST_P(QuicEventLoopFactoryTest, AlarmsInPast) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm1, delegate1] = CreateAlarm();
  auto [alarm2, delegate2] = CreateAlarm();

  alarm1->Set(clock_.Now() - 2 * kAlarmTimeout);
  alarm2->Set(clock_.Now() - kAlarmTimeout);

  {
    testing::InSequence s;
    EXPECT_CALL(*delegate1, OnAlarm());
    EXPECT_CALL(*delegate2, OnAlarm());
  }
  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(100));
}

TEST_P(QuicEventLoopFactoryTest, AlarmCancelled) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm, delegate] = CreateAlarm();

  alarm->Set(clock_.Now() + kAlarmTimeout);
  alarm->Cancel();

  loop_->RunEventLoopOnce(kAlarmTimeout * 2);
}

TEST_P(QuicEventLoopFactoryTest, AlarmCancelledAndSetAgain) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm, delegate] = CreateAlarm();

  alarm->Set(clock_.Now() + kAlarmTimeout);
  alarm->Cancel();
  alarm->Set(clock_.Now() + 2 * kAlarmTimeout);

  bool alarm_called = false;
  EXPECT_CALL(*delegate, OnAlarm()).WillOnce([&]() { alarm_called = true; });
  RunEventLoopUntil([&]() { return alarm_called; },
                    QuicTime::Delta::FromMilliseconds(100));
}

TEST_P(QuicEventLoopFactoryTest, AlarmCancelsAnotherAlarm) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm1_ptr, delegate1] = CreateAlarm();
  auto [alarm2_ptr, delegate2] = CreateAlarm();

  QuicAlarm& alarm1 = *alarm1_ptr;
  QuicAlarm& alarm2 = *alarm2_ptr;
  alarm1.Set(clock_.Now() - kAlarmTimeout);
  alarm2.Set(clock_.Now() - kAlarmTimeout);

  int alarms_called = 0;
  // Since the order in which alarms are cancelled is not well-determined, make
  // each one cancel another.
  EXPECT_CALL(*delegate1, OnAlarm()).Times(AtMost(1)).WillOnce([&]() {
    alarm2.Cancel();
    ++alarms_called;
  });
  EXPECT_CALL(*delegate2, OnAlarm()).Times(AtMost(1)).WillOnce([&]() {
    alarm1.Cancel();
    ++alarms_called;
  });
  // Run event loop twice to ensure the second alarm is not called after two
  // iterations.
  loop_->RunEventLoopOnce(kAlarmTimeout * 2);
  loop_->RunEventLoopOnce(kAlarmTimeout * 2);
  EXPECT_EQ(alarms_called, 1);
}

TEST_P(QuicEventLoopFactoryTest, DestructorWithPendingAlarm) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromMilliseconds(5);
  auto [alarm1_ptr, delegate1] = CreateAlarm();

  alarm1_ptr->Set(clock_.Now() + kAlarmTimeout);
  // Expect destructor to cleanly unregister itself before the event loop is
  // gone.
}

TEST_P(QuicEventLoopFactoryTest, NegativeTimeout) {
  constexpr auto kAlarmTimeout = QuicTime::Delta::FromSeconds(300);
  auto [alarm1_ptr, delegate1] = CreateAlarm();

  alarm1_ptr->Set(clock_.Now() + kAlarmTimeout);

  loop_->RunEventLoopOnce(QuicTime::Delta::FromMilliseconds(-1));
}

}  // namespace
}  // namespace quic::test
