#include "net/third_party/quiche/src/quic/core/legacy_quic_stream_id_manager.h"
#include "net/third_party/quiche/src/quic/core/quic_utils.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_ptr_util.h"
#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_session_peer.h"
#include "net/third_party/quiche/src/quic/test_tools/quic_test_utils.h"

namespace quic {
namespace test {
namespace {

using testing::_;
using testing::StrictMock;

class LegacyQuicStreamIdManagerTest : public QuicTest {
 protected:
  void Initialize(Perspective perspective) {
    SetQuicReloadableFlag(quic_enable_version_99, false);
    connection_ = new MockQuicConnection(
        &helper_, &alarm_factory_, perspective,
        ParsedVersionOfIndex(CurrentSupportedVersions(), 0));
    session_ = QuicMakeUnique<StrictMock<MockQuicSession>>(connection_);
    manager_ = QuicSessionPeer::GetStreamIdManager(session_.get());
    session_->Initialize();
  }

  QuicStreamId GetNthClientInitiatedId(int n) { return 3 + 2 * n; }

  QuicStreamId GetNthServerInitiatedId(int n) { return 2 + 2 * n; }

  MockQuicConnectionHelper helper_;
  MockAlarmFactory alarm_factory_;
  MockQuicConnection* connection_;
  std::unique_ptr<StrictMock<MockQuicSession>> session_;
  LegacyQuicStreamIdManager* manager_;
};

class LegacyQuicStreamIdManagerTestServer
    : public LegacyQuicStreamIdManagerTest {
 protected:
  LegacyQuicStreamIdManagerTestServer() { Initialize(Perspective::IS_SERVER); }
};

TEST_F(LegacyQuicStreamIdManagerTestServer, CanOpenNextOutgoingStream) {
  EXPECT_TRUE(manager_->CanOpenNextOutgoingStream(
      manager_->max_open_outgoing_streams() - 1));
  EXPECT_FALSE(manager_->CanOpenNextOutgoingStream(
      manager_->max_open_outgoing_streams()));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, CanOpenIncomingStream) {
  EXPECT_TRUE(manager_->CanOpenIncomingStream(
      manager_->max_open_incoming_streams() - 1));
  EXPECT_FALSE(
      manager_->CanOpenIncomingStream(manager_->max_open_incoming_streams()));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, AvailableStreams) {
  ASSERT_TRUE(
      manager_->MaybeIncreaseLargestPeerStreamId(GetNthClientInitiatedId(3)));
  EXPECT_TRUE(manager_->IsAvailableStream(GetNthClientInitiatedId(1)));
  EXPECT_TRUE(manager_->IsAvailableStream(GetNthClientInitiatedId(2)));
  ASSERT_TRUE(
      manager_->MaybeIncreaseLargestPeerStreamId(GetNthClientInitiatedId(2)));
  ASSERT_TRUE(
      manager_->MaybeIncreaseLargestPeerStreamId(GetNthClientInitiatedId(1)));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, MaxAvailableStreams) {
  // Test that the server closes the connection if a client makes too many data
  // streams available.  The server accepts slightly more than the negotiated
  // stream limit to deal with rare cases where a client FIN/RST is lost.
  const size_t kMaxStreamsForTest = 10;
  session_->OnConfigNegotiated();
  const size_t kAvailableStreamLimit = manager_->MaxAvailableStreams();
  EXPECT_EQ(
      manager_->max_open_incoming_streams() * kMaxAvailableStreamsMultiplier,
      manager_->MaxAvailableStreams());
  // The protocol specification requires that there can be at least 10 times
  // as many available streams as the connection's maximum open streams.
  EXPECT_LE(10 * kMaxStreamsForTest, kAvailableStreamLimit);

  EXPECT_TRUE(
      manager_->MaybeIncreaseLargestPeerStreamId(GetNthClientInitiatedId(0)));

  // Establish available streams up to the server's limit.
  const int kLimitingStreamId =
      GetNthClientInitiatedId(kAvailableStreamLimit + 1);
  // This exceeds the stream limit. In versions other than 99
  // this is allowed. Version 99 hews to the IETF spec and does
  // not allow it.
  EXPECT_TRUE(manager_->MaybeIncreaseLargestPeerStreamId(kLimitingStreamId));
  // A further available stream will result in connection close.
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));

  // This forces stream kLimitingStreamId + 2 to become available, which
  // violates the quota.
  EXPECT_FALSE(
      manager_->MaybeIncreaseLargestPeerStreamId(kLimitingStreamId + 2 * 2));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, MaximumAvailableOpenedStreams) {
  QuicStreamId stream_id = GetNthClientInitiatedId(0);
  EXPECT_TRUE(manager_->MaybeIncreaseLargestPeerStreamId(stream_id));

  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);
  EXPECT_TRUE(manager_->MaybeIncreaseLargestPeerStreamId(
      stream_id + 2 * (manager_->max_open_incoming_streams() - 1)));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, TooManyAvailableStreams) {
  QuicStreamId stream_id = GetNthClientInitiatedId(0);
  EXPECT_TRUE(manager_->MaybeIncreaseLargestPeerStreamId(stream_id));

  // A stream ID which is too large to create.
  QuicStreamId stream_id2 =
      GetNthClientInitiatedId(2 * manager_->MaxAvailableStreams() + 4);
  EXPECT_CALL(*connection_,
              CloseConnection(QUIC_TOO_MANY_AVAILABLE_STREAMS, _, _));
  EXPECT_FALSE(manager_->MaybeIncreaseLargestPeerStreamId(stream_id2));
}

TEST_F(LegacyQuicStreamIdManagerTestServer, ManyAvailableStreams) {
  // When max_open_streams_ is 200, should be able to create 200 streams
  // out-of-order, that is, creating the one with the largest stream ID first.
  manager_->set_max_open_incoming_streams(200);
  QuicStreamId stream_id = GetNthClientInitiatedId(0);
  EXPECT_TRUE(manager_->MaybeIncreaseLargestPeerStreamId(stream_id));
  EXPECT_CALL(*connection_, CloseConnection(_, _, _)).Times(0);

  // Create the largest stream ID of a threatened total of 200 streams.
  // GetNth... starts at 0, so for 200 streams, get the 199th.
  EXPECT_TRUE(
      manager_->MaybeIncreaseLargestPeerStreamId(GetNthClientInitiatedId(199)));
}

TEST_F(LegacyQuicStreamIdManagerTestServer,
       TestMaxIncomingAndOutgoingStreamsAllowed) {
  // Tests that on server side, the value of max_open_incoming/outgoing
  // streams are setup correctly during negotiation. The value for outgoing
  // stream is limited to negotiated value and for incoming stream it is set to
  // be larger than that.
  session_->OnConfigNegotiated();
  // The max number of open outgoing streams is less than that of incoming
  // streams, and it should be same as negotiated value.
  EXPECT_LT(manager_->max_open_outgoing_streams(),
            manager_->max_open_incoming_streams());
  EXPECT_EQ(manager_->max_open_outgoing_streams(),
            kDefaultMaxStreamsPerConnection);
  EXPECT_GT(manager_->max_open_incoming_streams(),
            kDefaultMaxStreamsPerConnection);
}

class LegacyQuicStreamIdManagerTestClient
    : public LegacyQuicStreamIdManagerTest {
 protected:
  LegacyQuicStreamIdManagerTestClient() { Initialize(Perspective::IS_CLIENT); }
};

TEST_F(LegacyQuicStreamIdManagerTestClient,
       TestMaxIncomingAndOutgoingStreamsAllowed) {
  // Tests that on client side, the value of max_open_incoming/outgoing
  // streams are setup correctly during negotiation. When flag is true, the
  // value for outgoing stream is limited to negotiated value and for incoming
  // stream it is set to be larger than that.
  session_->OnConfigNegotiated();
  EXPECT_LT(manager_->max_open_outgoing_streams(),
            manager_->max_open_incoming_streams());
  EXPECT_EQ(manager_->max_open_outgoing_streams(),
            kDefaultMaxStreamsPerConnection);
}

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