// Copyright (c) 2018 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 "quiche/quic/core/uber_quic_stream_id_manager.h"

#include "quiche/quic/core/quic_utils.h"
#include "quiche/quic/core/quic_versions.h"
#include "quiche/quic/platform/api/quic_test.h"
#include "quiche/quic/test_tools/quic_stream_id_manager_peer.h"
#include "quiche/quic/test_tools/quic_test_utils.h"

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

namespace quic {
namespace test {
namespace {

struct TestParams {
  explicit TestParams(ParsedQuicVersion version, Perspective perspective)
      : version(version), perspective(perspective) {}

  ParsedQuicVersion version;
  Perspective perspective;
};

// Used by ::testing::PrintToStringParamName().
std::string PrintToString(const TestParams& p) {
  return absl::StrCat(
      ParsedQuicVersionToString(p.version), "_",
      (p.perspective == Perspective::IS_CLIENT ? "client" : "server"));
}

std::vector<TestParams> GetTestParams() {
  std::vector<TestParams> params;
  for (const ParsedQuicVersion& version : AllSupportedVersions()) {
    if (!version.HasIetfQuicFrames()) {
      continue;
    }
    params.push_back(TestParams(version, Perspective::IS_CLIENT));
    params.push_back(TestParams(version, Perspective::IS_SERVER));
  }
  return params;
}

class MockDelegate : public QuicStreamIdManager::DelegateInterface {
 public:
  MOCK_METHOD(void, SendMaxStreams,
              (QuicStreamCount stream_count, bool unidirectional), (override));
};

class UberQuicStreamIdManagerTest : public QuicTestWithParam<TestParams> {
 protected:
  UberQuicStreamIdManagerTest()
      : manager_(perspective(), version(), &delegate_, 0, 0,
                 kDefaultMaxStreamsPerConnection,
                 kDefaultMaxStreamsPerConnection) {}

  QuicStreamId GetNthClientInitiatedBidirectionalId(int n) {
    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
                                                    Perspective::IS_CLIENT) +
           QuicUtils::StreamIdDelta(transport_version()) * n;
  }

  QuicStreamId GetNthClientInitiatedUnidirectionalId(int n) {
    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
                                                     Perspective::IS_CLIENT) +
           QuicUtils::StreamIdDelta(transport_version()) * n;
  }

  QuicStreamId GetNthServerInitiatedBidirectionalId(int n) {
    return QuicUtils::GetFirstBidirectionalStreamId(transport_version(),
                                                    Perspective::IS_SERVER) +
           QuicUtils::StreamIdDelta(transport_version()) * n;
  }

  QuicStreamId GetNthServerInitiatedUnidirectionalId(int n) {
    return QuicUtils::GetFirstUnidirectionalStreamId(transport_version(),
                                                     Perspective::IS_SERVER) +
           QuicUtils::StreamIdDelta(transport_version()) * n;
  }

  QuicStreamId GetNthPeerInitiatedBidirectionalStreamId(int n) {
    return ((perspective() == Perspective::IS_SERVER)
                ? GetNthClientInitiatedBidirectionalId(n)
                : GetNthServerInitiatedBidirectionalId(n));
  }
  QuicStreamId GetNthPeerInitiatedUnidirectionalStreamId(int n) {
    return ((perspective() == Perspective::IS_SERVER)
                ? GetNthClientInitiatedUnidirectionalId(n)
                : GetNthServerInitiatedUnidirectionalId(n));
  }
  QuicStreamId GetNthSelfInitiatedBidirectionalStreamId(int n) {
    return ((perspective() == Perspective::IS_CLIENT)
                ? GetNthClientInitiatedBidirectionalId(n)
                : GetNthServerInitiatedBidirectionalId(n));
  }
  QuicStreamId GetNthSelfInitiatedUnidirectionalStreamId(int n) {
    return ((perspective() == Perspective::IS_CLIENT)
                ? GetNthClientInitiatedUnidirectionalId(n)
                : GetNthServerInitiatedUnidirectionalId(n));
  }

  QuicStreamId StreamCountToId(QuicStreamCount stream_count,
                               Perspective perspective, bool bidirectional) {
    return ((bidirectional) ? QuicUtils::GetFirstBidirectionalStreamId(
                                  transport_version(), perspective)
                            : QuicUtils::GetFirstUnidirectionalStreamId(
                                  transport_version(), perspective)) +
           ((stream_count - 1) * QuicUtils::StreamIdDelta(transport_version()));
  }

  ParsedQuicVersion version() { return GetParam().version; }
  QuicTransportVersion transport_version() {
    return version().transport_version;
  }

  Perspective perspective() { return GetParam().perspective; }

  testing::StrictMock<MockDelegate> delegate_;
  UberQuicStreamIdManager manager_;
};

INSTANTIATE_TEST_SUITE_P(Tests, UberQuicStreamIdManagerTest,
                         ::testing::ValuesIn(GetTestParams()),
                         ::testing::PrintToStringParamName());

TEST_P(UberQuicStreamIdManagerTest, Initialization) {
  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
            manager_.next_outgoing_bidirectional_stream_id());
  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
            manager_.next_outgoing_unidirectional_stream_id());
}

TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreams) {
  const size_t kNumMaxOutgoingStream = 123;
  // Set the uni- and bi- directional limits to different values to ensure
  // that they are managed separately.
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
      kNumMaxOutgoingStream));
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
      kNumMaxOutgoingStream + 1));
  EXPECT_EQ(kNumMaxOutgoingStream,
            manager_.max_outgoing_bidirectional_streams());
  EXPECT_EQ(kNumMaxOutgoingStream + 1,
            manager_.max_outgoing_unidirectional_streams());
  // Check that, for each directionality, we can open the correct number of
  // streams.
  int i = kNumMaxOutgoingStream;
  while (i) {
    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
    manager_.GetNextOutgoingBidirectionalStreamId();
    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
    manager_.GetNextOutgoingUnidirectionalStreamId();
    i--;
  }
  // One more unidirectional
  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
  manager_.GetNextOutgoingUnidirectionalStreamId();

  // Both should be exhausted...
  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
}

TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenIncomingStreams) {
  const size_t kNumMaxIncomingStreams = 456;
  manager_.SetMaxOpenIncomingUnidirectionalStreams(kNumMaxIncomingStreams);
  // Do +1 for bidirectional to ensure that uni- and bi- get properly set.
  manager_.SetMaxOpenIncomingBidirectionalStreams(kNumMaxIncomingStreams + 1);
  EXPECT_EQ(kNumMaxIncomingStreams + 1,
            manager_.GetMaxAllowdIncomingBidirectionalStreams());
  EXPECT_EQ(kNumMaxIncomingStreams,
            manager_.GetMaxAllowdIncomingUnidirectionalStreams());
  EXPECT_EQ(manager_.max_incoming_bidirectional_streams(),
            manager_.advertised_max_incoming_bidirectional_streams());
  EXPECT_EQ(manager_.max_incoming_unidirectional_streams(),
            manager_.advertised_max_incoming_unidirectional_streams());
  // Make sure that we can create kNumMaxIncomingStreams incoming unidirectional
  // streams and kNumMaxIncomingStreams+1 incoming bidirectional streams.
  size_t i;
  for (i = 0; i < kNumMaxIncomingStreams; i++) {
    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
        GetNthPeerInitiatedUnidirectionalStreamId(i), nullptr));
    EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
        GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));
  }
  // Should be able to open the next bidirectional stream
  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthPeerInitiatedBidirectionalStreamId(i), nullptr));

  // We should have exhausted the counts, the next streams should fail
  std::string error_details;
  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthPeerInitiatedUnidirectionalStreamId(i), &error_details));
  EXPECT_EQ(error_details,
            absl::StrCat(
                "Stream id ", GetNthPeerInitiatedUnidirectionalStreamId(i),
                " would exceed stream count limit ", kNumMaxIncomingStreams));
  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthPeerInitiatedBidirectionalStreamId(i + 1), &error_details));
  EXPECT_EQ(error_details,
            absl::StrCat("Stream id ",
                         GetNthPeerInitiatedBidirectionalStreamId(i + 1),
                         " would exceed stream count limit ",
                         kNumMaxIncomingStreams + 1));
}

TEST_P(UberQuicStreamIdManagerTest, GetNextOutgoingStreamId) {
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(10));
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(10));
  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(0),
            manager_.GetNextOutgoingBidirectionalStreamId());
  EXPECT_EQ(GetNthSelfInitiatedBidirectionalStreamId(1),
            manager_.GetNextOutgoingBidirectionalStreamId());
  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(0),
            manager_.GetNextOutgoingUnidirectionalStreamId());
  EXPECT_EQ(GetNthSelfInitiatedUnidirectionalStreamId(1),
            manager_.GetNextOutgoingUnidirectionalStreamId());
}

TEST_P(UberQuicStreamIdManagerTest, AvailableStreams) {
  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthPeerInitiatedBidirectionalStreamId(3), nullptr));
  EXPECT_TRUE(
      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(1)));
  EXPECT_TRUE(
      manager_.IsAvailableStream(GetNthPeerInitiatedBidirectionalStreamId(2)));

  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
      GetNthPeerInitiatedUnidirectionalStreamId(3), nullptr));
  EXPECT_TRUE(
      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(1)));
  EXPECT_TRUE(
      manager_.IsAvailableStream(GetNthPeerInitiatedUnidirectionalStreamId(2)));
}

TEST_P(UberQuicStreamIdManagerTest, MaybeIncreaseLargestPeerStreamId) {
  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
                      QuicUtils::InvertPerspective(perspective()),
                      /* bidirectional=*/true),
      nullptr));
  EXPECT_TRUE(manager_.MaybeIncreaseLargestPeerStreamId(
      StreamCountToId(manager_.max_incoming_bidirectional_streams(),
                      QuicUtils::InvertPerspective(perspective()),
                      /* bidirectional=*/false),
      nullptr));

  std::string expected_error_details =
      perspective() == Perspective::IS_SERVER
          ? "Stream id 400 would exceed stream count limit 100"
          : "Stream id 401 would exceed stream count limit 100";
  std::string error_details;

  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
                      QuicUtils::InvertPerspective(perspective()),
                      /* bidirectional=*/true),
      &error_details));
  EXPECT_EQ(expected_error_details, error_details);
  expected_error_details =
      perspective() == Perspective::IS_SERVER
          ? "Stream id 402 would exceed stream count limit 100"
          : "Stream id 403 would exceed stream count limit 100";

  EXPECT_FALSE(manager_.MaybeIncreaseLargestPeerStreamId(
      StreamCountToId(manager_.max_incoming_bidirectional_streams() + 1,
                      QuicUtils::InvertPerspective(perspective()),
                      /* bidirectional=*/false),
      &error_details));
  EXPECT_EQ(expected_error_details, error_details);
}

TEST_P(UberQuicStreamIdManagerTest, OnStreamsBlockedFrame) {
  QuicStreamCount stream_count =
      manager_.advertised_max_incoming_bidirectional_streams() - 1;

  QuicStreamsBlockedFrame frame(kInvalidControlFrameId, stream_count,
                                /*unidirectional=*/false);
  EXPECT_CALL(delegate_,
              SendMaxStreams(manager_.max_incoming_bidirectional_streams(),
                             frame.unidirectional))
      .Times(0);
  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));

  stream_count = manager_.advertised_max_incoming_unidirectional_streams() - 1;
  frame.stream_count = stream_count;
  frame.unidirectional = true;

  EXPECT_CALL(delegate_,
              SendMaxStreams(manager_.max_incoming_unidirectional_streams(),
                             frame.unidirectional))
      .Times(0);
  EXPECT_TRUE(manager_.OnStreamsBlockedFrame(frame, nullptr));
}

TEST_P(UberQuicStreamIdManagerTest, SetMaxOpenOutgoingStreamsPlusFrame) {
  const size_t kNumMaxOutgoingStream = 123;
  // Set the uni- and bi- directional limits to different values to ensure
  // that they are managed separately.
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingBidirectionalStreams(
      kNumMaxOutgoingStream));
  EXPECT_TRUE(manager_.MaybeAllowNewOutgoingUnidirectionalStreams(
      kNumMaxOutgoingStream + 1));
  EXPECT_EQ(kNumMaxOutgoingStream,
            manager_.max_outgoing_bidirectional_streams());
  EXPECT_EQ(kNumMaxOutgoingStream + 1,
            manager_.max_outgoing_unidirectional_streams());
  // Check that, for each directionality, we can open the correct number of
  // streams.
  int i = kNumMaxOutgoingStream;
  while (i) {
    EXPECT_TRUE(manager_.CanOpenNextOutgoingBidirectionalStream());
    manager_.GetNextOutgoingBidirectionalStreamId();
    EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
    manager_.GetNextOutgoingUnidirectionalStreamId();
    i--;
  }
  // One more unidirectional
  EXPECT_TRUE(manager_.CanOpenNextOutgoingUnidirectionalStream());
  manager_.GetNextOutgoingUnidirectionalStreamId();

  // Both should be exhausted...
  EXPECT_FALSE(manager_.CanOpenNextOutgoingUnidirectionalStream());
  EXPECT_FALSE(manager_.CanOpenNextOutgoingBidirectionalStream());
}

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