// Copyright (c) 2019 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 "net/third_party/quiche/src/spdy/core/lifo_write_scheduler.h"

#include "net/third_party/quiche/src/common/platform/api/quiche_test.h"
#include "net/third_party/quiche/src/spdy/core/spdy_protocol.h"
#include "net/third_party/quiche/src/spdy/core/spdy_test_utils.h"
#include "net/third_party/quiche/src/spdy/platform/api/spdy_test_helpers.h"

namespace spdy {

namespace test {

template <typename StreamIdType>
class LifoWriteSchedulerPeer {
 public:
  explicit LifoWriteSchedulerPeer(LifoWriteScheduler<StreamIdType>* scheduler)
      : scheduler_(scheduler) {}

  size_t NumRegisteredListStreams() const {
    return scheduler_->registered_streams_.size();
  }

  std::set<StreamIdType>* GetReadyList() const {
    return &scheduler_->ready_streams_;
  }

 private:
  LifoWriteScheduler<StreamIdType>* scheduler_;
};

// Test add and remove from ready list.
TEST(LifoWriteSchedulerTest, ReadyListTest) {
  LifoWriteScheduler<SpdyStreamId> lifo;
  LifoWriteSchedulerPeer<SpdyStreamId> peer(&lifo);

  EXPECT_SPDY_BUG(
      EXPECT_EQ(0u, std::get<0>(lifo.PopNextReadyStreamAndPrecedence())),
      "No ready streams available");
  EXPECT_SPDY_BUG(EXPECT_EQ(0u, lifo.PopNextReadyStream()),
                  "No ready streams available");
  EXPECT_FALSE(lifo.HasReadyStreams());
  EXPECT_SPDY_BUG(lifo.MarkStreamReady(9, true), "Stream 9 is not registered");
  EXPECT_SPDY_BUG(lifo.IsStreamReady(9), "Stream 9 is not registered");
  SpdyStreamPrecedence precedence(1);
  lifo.RegisterStream(3, precedence);
  EXPECT_FALSE(lifo.IsStreamReady(3));
  lifo.RegisterStream(7, precedence);
  lifo.RegisterStream(9, precedence);
  lifo.RegisterStream(11, precedence);
  lifo.RegisterStream(13, precedence);
  lifo.RegisterStream(15, precedence);
  lifo.RegisterStream(17, precedence);
  lifo.MarkStreamReady(9, true);
  lifo.MarkStreamReady(15, true);
  lifo.MarkStreamReady(7, true);
  lifo.MarkStreamReady(13, true);
  lifo.MarkStreamReady(11, true);
  lifo.MarkStreamReady(3, true);
  EXPECT_TRUE(lifo.IsStreamReady(3));
  lifo.MarkStreamReady(17, true);
  EXPECT_TRUE(lifo.HasReadyStreams());
  EXPECT_EQ(7u, lifo.NumReadyStreams());

  // Verify MarkStream(Not)Ready() can be called multiple times for the same
  // stream.
  lifo.MarkStreamReady(11, true);
  lifo.MarkStreamNotReady(5);
  lifo.MarkStreamNotReady(21);

  EXPECT_EQ(17u, lifo.PopNextReadyStream());
  EXPECT_EQ(15u, std::get<0>(lifo.PopNextReadyStreamAndPrecedence()));
  EXPECT_TRUE(lifo.ShouldYield(9));
  EXPECT_FALSE(lifo.ShouldYield(13));
  EXPECT_FALSE(lifo.ShouldYield(15));

  lifo.MarkStreamNotReady(3);
  EXPECT_TRUE(peer.GetReadyList()->find(3) == peer.GetReadyList()->end());
  lifo.MarkStreamNotReady(13);
  EXPECT_TRUE(peer.GetReadyList()->find(13) == peer.GetReadyList()->end());
  lifo.MarkStreamNotReady(7);
  EXPECT_TRUE(peer.GetReadyList()->find(7) == peer.GetReadyList()->end());
  EXPECT_EQ(2u, lifo.NumReadyStreams());

  lifo.MarkStreamNotReady(9);
  lifo.MarkStreamNotReady(11);
  EXPECT_FALSE(lifo.ShouldYield(1));
}

// Test add and remove from registered list.
TEST(LifoWriteSchedulerTest, RegisterListTest) {
  LifoWriteScheduler<SpdyStreamId> lifo;
  LifoWriteSchedulerPeer<SpdyStreamId> peer(&lifo);
  SpdyStreamPrecedence precedence(1);
  EXPECT_EQ(0u, lifo.NumRegisteredStreams());
  lifo.RegisterStream(3, precedence);
  lifo.RegisterStream(5, precedence);
  lifo.RegisterStream(7, precedence);
  lifo.RegisterStream(9, precedence);
  lifo.RegisterStream(11, precedence);
  EXPECT_EQ(5u, lifo.NumRegisteredStreams());

  EXPECT_TRUE(lifo.StreamRegistered(3));
  EXPECT_TRUE(lifo.StreamRegistered(5));
  EXPECT_TRUE(lifo.StreamRegistered(7));
  EXPECT_TRUE(lifo.StreamRegistered(9));
  EXPECT_TRUE(lifo.StreamRegistered(11));
  EXPECT_SPDY_BUG(lifo.RegisterStream(11, precedence),
                  "Stream 11 already registered");
  EXPECT_EQ(5u, peer.NumRegisteredListStreams());

  lifo.UnregisterStream(3);
  EXPECT_EQ(4u, lifo.NumRegisteredStreams());
  EXPECT_FALSE(lifo.StreamRegistered(3));
  EXPECT_SPDY_BUG(lifo.UnregisterStream(3), "Stream 3 is not registered");
  EXPECT_SPDY_BUG(lifo.UnregisterStream(13), "Stream 13 is not registered");
  lifo.UnregisterStream(11);
  EXPECT_FALSE(lifo.StreamRegistered(11));
  lifo.UnregisterStream(7);
  EXPECT_EQ(2u, lifo.NumRegisteredStreams());
  EXPECT_FALSE(lifo.StreamRegistered(7));
  EXPECT_TRUE(lifo.StreamRegistered(5));
  EXPECT_TRUE(lifo.StreamRegistered(9));
}

// Test mark latest event time.
TEST(LifoWriteSchedulerTest, GetLatestEventTest) {
  LifoWriteScheduler<SpdyStreamId> lifo;
  LifoWriteSchedulerPeer<SpdyStreamId> peer(&lifo);
  SpdyStreamPrecedence precedence(1);
  lifo.RegisterStream(1, precedence);
  lifo.RegisterStream(3, precedence);
  lifo.RegisterStream(5, precedence);
  lifo.RegisterStream(7, precedence);
  lifo.RegisterStream(9, precedence);
  lifo.RecordStreamEventTime(1, 1);
  lifo.RecordStreamEventTime(3, 8);
  lifo.RecordStreamEventTime(5, 4);
  lifo.RecordStreamEventTime(7, 2);
  lifo.RecordStreamEventTime(9, 3);
  EXPECT_SPDY_BUG(lifo.RecordStreamEventTime(11, 1),
                  "Stream 11 is not registered");
  EXPECT_EQ(0, lifo.GetLatestEventWithPrecedence(9));
  EXPECT_EQ(3, lifo.GetLatestEventWithPrecedence(7));
  EXPECT_EQ(3, lifo.GetLatestEventWithPrecedence(5));
  EXPECT_EQ(4, lifo.GetLatestEventWithPrecedence(3));
  EXPECT_EQ(8, lifo.GetLatestEventWithPrecedence(1));
  EXPECT_SPDY_BUG(lifo.GetLatestEventWithPrecedence(11),
                  "Stream 11 is not registered");
}

TEST(LifoWriteSchedulerTest, GetStreamPrecedence) {
  LifoWriteScheduler<SpdyStreamId> lifo;
  // Return lowest priority for unknown stream.
  EXPECT_EQ(kV3LowestPriority, lifo.GetStreamPrecedence(1).spdy3_priority());

  lifo.RegisterStream(1, SpdyStreamPrecedence(3));
  EXPECT_TRUE(lifo.GetStreamPrecedence(1).is_spdy3_priority());
  EXPECT_EQ(3, lifo.GetStreamPrecedence(1).spdy3_priority());

  // Redundant registration shouldn't change stream priority.
  EXPECT_SPDY_BUG(lifo.RegisterStream(1, SpdyStreamPrecedence(4)),
                  "Stream 1 already registered");
  EXPECT_EQ(3, lifo.GetStreamPrecedence(1).spdy3_priority());

  lifo.UpdateStreamPrecedence(1, SpdyStreamPrecedence(5));
  EXPECT_EQ(5, lifo.GetStreamPrecedence(1).spdy3_priority());
}

}  // namespace test

}  // namespace spdy
