// 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/ascii.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"

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_->GetAlarmFactory()) {
    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_;
  QuicAlarmFactory* factory_;
  int read_fd_;
  int write_fd_;
};

std::string GetTestParamName(
    ::testing::TestParamInfo<QuicEventLoopFactory*> info) {
  std::string name = info.param->GetName();
  // Escape all characters that are not allowed by gtest ([a-zA-Z0-9_]).
  for (char& c : name) {
    bool valid = absl::ascii_isalnum(c) || c == '_';
    if (!valid) {
      c = '_';
    }
  }
  return name;
}

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);
}

// 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.
}

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