#include "quiche/http2/adapter/window_manager.h"

#include <list>

#include "absl/functional/bind_front.h"
#include "quiche/http2/test_tools/http2_random.h"
#include "quiche/common/platform/api/quiche_expect_bug.h"
#include "quiche/common/platform/api/quiche_test.h"

namespace http2 {
namespace adapter {
namespace test {

// Use the peer to access private vars of WindowManager.
class WindowManagerPeer {
 public:
  explicit WindowManagerPeer(const WindowManager& wm) : wm_(wm) {}

  int64_t buffered() { return wm_.buffered_; }

 private:
  const WindowManager& wm_;
};

namespace {

class WindowManagerTest : public ::testing::Test {
 protected:
  WindowManagerTest()
      : wm_(kDefaultLimit, absl::bind_front(&WindowManagerTest::OnCall, this)),
        peer_(wm_) {}

  void OnCall(int64_t s) { call_sequence_.push_back(s); }

  const int64_t kDefaultLimit = 32 * 1024 * 3;
  std::list<int64_t> call_sequence_;
  WindowManager wm_;
  WindowManagerPeer peer_;
  ::http2::test::Http2Random random_;
};

// A few no-op calls.
TEST_F(WindowManagerTest, NoOps) {
  wm_.SetWindowSizeLimit(kDefaultLimit);
  wm_.SetWindowSizeLimit(0);
  wm_.SetWindowSizeLimit(kDefaultLimit);
  wm_.MarkDataBuffered(0);
  wm_.MarkDataFlushed(0);
  EXPECT_TRUE(call_sequence_.empty());
}

// This test verifies that WindowManager does not notify its listener when data
// is only buffered, and never flushed.
TEST_F(WindowManagerTest, DataOnlyBuffered) {
  int64_t total = 0;
  while (total < kDefaultLimit) {
    int64_t s = std::min<int64_t>(kDefaultLimit - total, random_.Uniform(1024));
    total += s;
    wm_.MarkDataBuffered(s);
  }
  EXPECT_THAT(call_sequence_, ::testing::IsEmpty());
}

// This test verifies that WindowManager does notify its listener when data is
// buffered and subsequently flushed.
TEST_F(WindowManagerTest, DataBufferedAndFlushed) {
  int64_t total_buffered = 0;
  int64_t total_flushed = 0;
  while (call_sequence_.empty()) {
    int64_t buffered = std::min<int64_t>(kDefaultLimit - total_buffered,
                                         random_.Uniform(1024));
    wm_.MarkDataBuffered(buffered);
    total_buffered += buffered;
    EXPECT_TRUE(call_sequence_.empty());
    int64_t flushed = random_.Uniform(total_buffered - total_flushed);
    wm_.MarkDataFlushed(flushed);
    total_flushed += flushed;
  }
  // If WindowManager decided to send an update, at least one third of the
  // window must have been consumed by buffered data.
  EXPECT_GE(total_buffered, kDefaultLimit / 3);
}

// Window manager should avoid window underflow.
TEST_F(WindowManagerTest, AvoidWindowUnderflow) {
  EXPECT_EQ(wm_.CurrentWindowSize(), wm_.WindowSizeLimit());
  // Don't buffer more than the total window!
  wm_.MarkDataBuffered(wm_.WindowSizeLimit() + 1);
  EXPECT_EQ(wm_.CurrentWindowSize(), 0u);
}

// Window manager should GFE_BUG and avoid buffered underflow.
TEST_F(WindowManagerTest, AvoidBufferedUnderflow) {
  EXPECT_EQ(peer_.buffered(), 0u);
  // Don't flush more than has been buffered!
  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(1), "buffered underflow");
  EXPECT_EQ(peer_.buffered(), 0u);

  wm_.MarkDataBuffered(42);
  EXPECT_EQ(peer_.buffered(), 42u);
  // Don't flush more than has been buffered!
  EXPECT_QUICHE_BUG(wm_.MarkDataFlushed(43), "buffered underflow");
  EXPECT_EQ(peer_.buffered(), 0u);
}

// This test verifies that WindowManager notifies its listener when window is
// consumed (data is ignored or immediately dropped).
TEST_F(WindowManagerTest, WindowConsumed) {
  int64_t consumed = kDefaultLimit / 3 - 1;
  wm_.MarkWindowConsumed(consumed);
  EXPECT_TRUE(call_sequence_.empty());
  const int64_t extra = 1;
  wm_.MarkWindowConsumed(extra);
  EXPECT_THAT(call_sequence_, testing::ElementsAre(consumed + extra));
}

// This test verifies that WindowManager notifies its listener when the window
// size limit is increased.
TEST_F(WindowManagerTest, ListenerCalledOnSizeUpdate) {
  wm_.SetWindowSizeLimit(kDefaultLimit - 1024);
  EXPECT_TRUE(call_sequence_.empty());
  wm_.SetWindowSizeLimit(kDefaultLimit * 5);
  // Because max(outstanding window, previous limit) is kDefaultLimit, it is
  // only appropriate to increase the window by kDefaultLimit * 4.
  EXPECT_THAT(call_sequence_, testing::ElementsAre(kDefaultLimit * 4));
}

// This test verifies that when data is buffered and then the limit is
// decreased, WindowManager only notifies the listener once any outstanding
// window has been consumed.
TEST_F(WindowManagerTest, WindowUpdateAfterLimitDecreased) {
  wm_.MarkDataBuffered(kDefaultLimit - 1024);
  wm_.SetWindowSizeLimit(kDefaultLimit - 2048);

  // Now there are 2048 bytes of window outstanding beyond the current limit,
  // and we have 1024 bytes of data buffered beyond the current limit. This is
  // intentional, to be sure that WindowManager works properly if the limit is
  // decreased at runtime.

  wm_.MarkDataFlushed(512);
  EXPECT_TRUE(call_sequence_.empty());
  wm_.MarkDataFlushed(512);
  EXPECT_TRUE(call_sequence_.empty());
  wm_.MarkDataFlushed(512);
  EXPECT_TRUE(call_sequence_.empty());
  wm_.MarkDataFlushed(1024);
  EXPECT_THAT(call_sequence_, testing::ElementsAre(512));
}

// For normal behavior, we only call MaybeNotifyListener() when data is
// flushed. But if window runs out entirely, we still need to call
// MaybeNotifyListener() to avoid becoming artificially blocked when data isn't
// being flushed.
TEST_F(WindowManagerTest, ZeroWindowNotification) {
  // Consume a byte of window, but not enough to trigger an update.
  wm_.MarkWindowConsumed(1);

  // Buffer the remaining window.
  wm_.MarkDataBuffered(kDefaultLimit - 1);
  // Listener is notified of the remaining byte of possible window.
  EXPECT_THAT(call_sequence_, testing::ElementsAre(1));
}

TEST_F(WindowManagerTest, OnWindowSizeLimitChange) {
  wm_.MarkDataBuffered(10000);
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 10000);
  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);

  wm_.OnWindowSizeLimitChange(kDefaultLimit + 1000);
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 9000);
  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit + 1000);

  wm_.OnWindowSizeLimitChange(kDefaultLimit - 1000);
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 11000);
  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit - 1000);
}

TEST_F(WindowManagerTest, NegativeWindowSize) {
  wm_.MarkDataBuffered(80000);
  // 98304 window - 80000 buffered = 18304 available
  EXPECT_EQ(wm_.CurrentWindowSize(), 18304);
  wm_.OnWindowSizeLimitChange(65535);
  // limit decreases by 98304 - 65535 = 32769, window becomes -14465
  EXPECT_EQ(wm_.CurrentWindowSize(), -14465);
  wm_.MarkDataFlushed(70000);
  // Still 10000 bytes buffered, so window manager grants sufficient quota to
  // reach a window of 65535 - 10000.
  EXPECT_EQ(wm_.CurrentWindowSize(), 55535);
  // Desired window minus existing window: 55535 - (-14465) = 70000
  EXPECT_THAT(call_sequence_, testing::ElementsAre(70000));
}

TEST_F(WindowManagerTest, IncreaseWindow) {
  wm_.MarkDataBuffered(1000);
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);

  // Increasing the window beyond the limit is allowed.
  wm_.IncreaseWindow(5000);
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit + 4000);
  EXPECT_EQ(wm_.WindowSizeLimit(), kDefaultLimit);

  // 80000 bytes are buffered, then flushed.
  wm_.MarkWindowConsumed(80000);
  // The window manager replenishes the consumed quota up to the limit.
  EXPECT_THAT(call_sequence_, testing::ElementsAre(75000));
  // The window is the limit, minus buffered data, as expected.
  EXPECT_EQ(wm_.CurrentWindowSize(), kDefaultLimit - 1000);
}

// This test verifies that when the constructor option is specified,
// WindowManager does not update its internal accounting of the flow control
// window when notifying the listener.
TEST(WindowManagerNoUpdateTest, NoWindowUpdateOnListener) {
  const int64_t kDefaultLimit = 65535;

  std::list<int64_t> call_sequence1;
  WindowManager wm1(
      kDefaultLimit,
      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
      /*should_notify_listener=*/{},
      /*update_window_on_notify=*/true);  // default
  std::list<int64_t> call_sequence2;
  WindowManager wm2(
      kDefaultLimit,
      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
      /*should_notify_listener=*/{},
      /*update_window_on_notify=*/false);

  const int64_t consumed = kDefaultLimit / 3 - 1;

  wm1.MarkWindowConsumed(consumed);
  EXPECT_TRUE(call_sequence1.empty());
  wm2.MarkWindowConsumed(consumed);
  EXPECT_TRUE(call_sequence2.empty());

  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit - consumed);
  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - consumed);

  const int64_t extra = 1;
  wm1.MarkWindowConsumed(extra);
  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed + extra));
  // Window size *is* updated after invoking the listener.
  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit);
  call_sequence1.clear();

  wm2.MarkWindowConsumed(extra);
  EXPECT_THAT(call_sequence2, testing::ElementsAre(consumed + extra));
  // Window size is *not* updated after invoking the listener.
  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit - (consumed + extra));
  call_sequence2.clear();

  // Manually increase the window by the listener notification amount.
  wm2.IncreaseWindow(consumed + extra);
  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);

  wm1.SetWindowSizeLimit(kDefaultLimit * 5);
  EXPECT_THAT(call_sequence1, testing::ElementsAre(kDefaultLimit * 4));
  // *Does* update the window size.
  EXPECT_EQ(wm1.CurrentWindowSize(), kDefaultLimit * 5);

  wm2.SetWindowSizeLimit(kDefaultLimit * 5);
  EXPECT_THAT(call_sequence2, testing::ElementsAre(kDefaultLimit * 4));
  // Does *not* update the window size.
  EXPECT_EQ(wm2.CurrentWindowSize(), kDefaultLimit);
}

// This test verifies that when the constructor option is specified,
// WindowManager uses the provided ShouldWindowUpdateFn to determine when to
// notify the listener.
TEST(WindowManagerShouldUpdateTest, CustomShouldWindowUpdateFn) {
  const int64_t kDefaultLimit = 65535;

  // This window manager should always notify.
  std::list<int64_t> call_sequence1;
  WindowManager wm1(
      kDefaultLimit,
      [&call_sequence1](int64_t delta) { call_sequence1.push_back(delta); },
      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
        return true;
      });
  // This window manager should never notify.
  std::list<int64_t> call_sequence2;
  WindowManager wm2(
      kDefaultLimit,
      [&call_sequence2](int64_t delta) { call_sequence2.push_back(delta); },
      [](int64_t /*limit*/, int64_t /*window*/, int64_t /*delta*/) {
        return false;
      });
  // This window manager should notify as long as no data is buffered.
  std::list<int64_t> call_sequence3;
  WindowManager wm3(
      kDefaultLimit,
      [&call_sequence3](int64_t delta) { call_sequence3.push_back(delta); },
      [](int64_t limit, int64_t window, int64_t delta) {
        return delta == limit - window;
      });

  const int64_t consumed = kDefaultLimit / 4;

  wm1.MarkWindowConsumed(consumed);
  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
  wm2.MarkWindowConsumed(consumed);
  EXPECT_TRUE(call_sequence2.empty());
  wm3.MarkWindowConsumed(consumed);
  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));

  const int64_t buffered = 42;

  wm1.MarkDataBuffered(buffered);
  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed));
  wm2.MarkDataBuffered(buffered);
  EXPECT_TRUE(call_sequence2.empty());
  wm3.MarkDataBuffered(buffered);
  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));

  wm1.MarkDataFlushed(buffered / 3);
  EXPECT_THAT(call_sequence1, testing::ElementsAre(consumed, buffered / 3));
  wm2.MarkDataFlushed(buffered / 3);
  EXPECT_TRUE(call_sequence2.empty());
  wm3.MarkDataFlushed(buffered / 3);
  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed));

  wm1.MarkDataFlushed(2 * buffered / 3);
  EXPECT_THAT(call_sequence1,
              testing::ElementsAre(consumed, buffered / 3, 2 * buffered / 3));
  wm2.MarkDataFlushed(2 * buffered / 3);
  EXPECT_TRUE(call_sequence2.empty());
  wm3.MarkDataFlushed(2 * buffered / 3);
  EXPECT_THAT(call_sequence3, testing::ElementsAre(consumed, buffered));
}

}  // namespace
}  // namespace test
}  // namespace adapter
}  // namespace http2
