/*
 *  Copyright (c) 2021 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */
#include "net/dcsctp/socket/stream_reset_handler.h"

#include <array>
#include <cstdint>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "api/task_queue/task_queue_base.h"
#include "api/units/time_delta.h"
#include "net/dcsctp/common/handover_testing.h"
#include "net/dcsctp/common/internal_types.h"
#include "net/dcsctp/packet/chunk/forward_tsn_common.h"
#include "net/dcsctp/packet/chunk/reconfig_chunk.h"
#include "net/dcsctp/packet/parameter/incoming_ssn_reset_request_parameter.h"
#include "net/dcsctp/packet/parameter/outgoing_ssn_reset_request_parameter.h"
#include "net/dcsctp/packet/parameter/parameter.h"
#include "net/dcsctp/packet/parameter/reconfiguration_response_parameter.h"
#include "net/dcsctp/packet/sctp_packet.h"
#include "net/dcsctp/public/dcsctp_handover_state.h"
#include "net/dcsctp/public/dcsctp_options.h"
#include "net/dcsctp/public/types.h"
#include "net/dcsctp/rx/data_tracker.h"
#include "net/dcsctp/rx/reassembly_queue.h"
#include "net/dcsctp/socket/mock_context.h"
#include "net/dcsctp/socket/mock_dcsctp_socket_callbacks.h"
#include "net/dcsctp/testing/data_generator.h"
#include "net/dcsctp/testing/testing_macros.h"
#include "net/dcsctp/timer/timer.h"
#include "net/dcsctp/tx/mock_send_queue.h"
#include "net/dcsctp/tx/retransmission_queue.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace dcsctp {
namespace {
using ::testing::IsEmpty;
using ::testing::NiceMock;
using ::testing::Optional;
using ::testing::Property;
using ::testing::Return;
using ::testing::SizeIs;
using ::testing::UnorderedElementsAre;
using ::webrtc::TimeDelta;
using ResponseResult = ReconfigurationResponseParameter::Result;
using SkippedStream = AnyForwardTsnChunk::SkippedStream;

constexpr TSN kMyInitialTsn = MockContext::MyInitialTsn();
constexpr ReconfigRequestSN kMyInitialReqSn = ReconfigRequestSN(*kMyInitialTsn);
constexpr TSN kPeerInitialTsn = MockContext::PeerInitialTsn();
constexpr ReconfigRequestSN kPeerInitialReqSn =
    ReconfigRequestSN(*kPeerInitialTsn);
constexpr uint32_t kArwnd = 131072;
constexpr TimeDelta kRto = TimeDelta::Millis(250);

constexpr std::array<uint8_t, 4> kShortPayload = {1, 2, 3, 4};

MATCHER_P3(SctpMessageIs, stream_id, ppid, expected_payload, "") {
  if (arg.stream_id() != stream_id) {
    *result_listener << "the stream_id is " << *arg.stream_id();
    return false;
  }

  if (arg.ppid() != ppid) {
    *result_listener << "the ppid is " << *arg.ppid();
    return false;
  }

  if (std::vector<uint8_t>(arg.payload().begin(), arg.payload().end()) !=
      std::vector<uint8_t>(expected_payload.begin(), expected_payload.end())) {
    *result_listener << "the payload is wrong";
    return false;
  }
  return true;
}

TSN AddTo(TSN tsn, int delta) {
  return TSN(*tsn + delta);
}

ReconfigRequestSN AddTo(ReconfigRequestSN req_sn, int delta) {
  return ReconfigRequestSN(*req_sn + delta);
}

class StreamResetHandlerTest : public testing::Test {
 protected:
  StreamResetHandlerTest()
      : ctx_(&callbacks_),
        timer_manager_([this](webrtc::TaskQueueBase::DelayPrecision precision) {
          return callbacks_.CreateTimeout(precision);
        }),
        delayed_ack_timer_(timer_manager_.CreateTimer(
            "test/delayed_ack",
            []() { return TimeDelta::Zero(); },
            TimerOptions(TimeDelta::Zero()))),
        t3_rtx_timer_(timer_manager_.CreateTimer(
            "test/t3_rtx",
            []() { return TimeDelta::Zero(); },
            TimerOptions(TimeDelta::Zero()))),
        data_tracker_(std::make_unique<DataTracker>("log: ",
                                                    delayed_ack_timer_.get(),
                                                    kPeerInitialTsn)),
        reasm_(std::make_unique<ReassemblyQueue>("log: ", kArwnd)),
        retransmission_queue_(std::make_unique<RetransmissionQueue>(
            "",
            &callbacks_,
            kMyInitialTsn,
            kArwnd,
            producer_,
            [](TimeDelta /* rtt */) {},
            []() {},
            *t3_rtx_timer_,
            DcSctpOptions())),
        handler_(
            std::make_unique<StreamResetHandler>("log: ",
                                                 &ctx_,
                                                 &timer_manager_,
                                                 data_tracker_.get(),
                                                 reasm_.get(),
                                                 retransmission_queue_.get())) {
    EXPECT_CALL(ctx_, current_rto).WillRepeatedly(Return(kRto));
  }

  void AdvanceTime(TimeDelta duration) {
    callbacks_.AdvanceTime(duration);
    for (;;) {
      std::optional<TimeoutID> timeout_id = callbacks_.GetNextExpiredTimeout();
      if (!timeout_id.has_value()) {
        break;
      }
      timer_manager_.HandleTimeout(*timeout_id);
    }
  }

  // Handles the passed in RE-CONFIG `chunk` and returns the responses
  // that are sent in the response RE-CONFIG.
  std::vector<ReconfigurationResponseParameter> HandleAndCatchResponse(
      ReConfigChunk chunk) {
    handler_->HandleReConfig(std::move(chunk));

    std::vector<uint8_t> payload = callbacks_.ConsumeSentPacket();
    if (payload.empty()) {
      EXPECT_TRUE(false);
      return {};
    }

    std::vector<ReconfigurationResponseParameter> responses;
    std::optional<SctpPacket> p = SctpPacket::Parse(payload, DcSctpOptions());
    if (!p.has_value()) {
      EXPECT_TRUE(false);
      return {};
    }
    if (p->descriptors().size() != 1) {
      EXPECT_TRUE(false);
      return {};
    }
    std::optional<ReConfigChunk> response_chunk =
        ReConfigChunk::Parse(p->descriptors()[0].data);
    if (!response_chunk.has_value()) {
      EXPECT_TRUE(false);
      return {};
    }
    for (const auto& desc : response_chunk->parameters().descriptors()) {
      if (desc.type == ReconfigurationResponseParameter::kType) {
        std::optional<ReconfigurationResponseParameter> response =
            ReconfigurationResponseParameter::Parse(desc.data);
        if (!response.has_value()) {
          EXPECT_TRUE(false);
          return {};
        }
        responses.emplace_back(*std::move(response));
      }
    }
    return responses;
  }

  void PerformHandover() {
    EXPECT_TRUE(handler_->GetHandoverReadiness().IsReady());
    EXPECT_TRUE(data_tracker_->GetHandoverReadiness().IsReady());
    EXPECT_TRUE(reasm_->GetHandoverReadiness().IsReady());
    EXPECT_TRUE(retransmission_queue_->GetHandoverReadiness().IsReady());

    DcSctpSocketHandoverState state;
    handler_->AddHandoverState(state);
    data_tracker_->AddHandoverState(state);
    reasm_->AddHandoverState(state);

    retransmission_queue_->AddHandoverState(callbacks_.Now(), state);

    g_handover_state_transformer_for_test(&state);

    data_tracker_ = std::make_unique<DataTracker>(
        "log: ", delayed_ack_timer_.get(), kPeerInitialTsn);
    data_tracker_->RestoreFromState(state);
    reasm_ = std::make_unique<ReassemblyQueue>("log: ", kArwnd);
    reasm_->RestoreFromState(state);
    retransmission_queue_ = std::make_unique<RetransmissionQueue>(
        "", &callbacks_, kMyInitialTsn, kArwnd, producer_,
        [](TimeDelta /* rtt */) {}, []() {}, *t3_rtx_timer_, DcSctpOptions(),
        /*supports_partial_reliability=*/true,
        /*use_message_interleaving=*/false);
    retransmission_queue_->RestoreFromState(callbacks_.Now(), state);
    handler_ = std::make_unique<StreamResetHandler>(
        "log: ", &ctx_, &timer_manager_, data_tracker_.get(), reasm_.get(),
        retransmission_queue_.get(), &state);
  }

  DataGenerator gen_;
  NiceMock<MockDcSctpSocketCallbacks> callbacks_;
  NiceMock<MockContext> ctx_;
  NiceMock<MockSendQueue> producer_;
  TimerManager timer_manager_;
  std::unique_ptr<Timer> delayed_ack_timer_;
  std::unique_ptr<Timer> t3_rtx_timer_;
  std::unique_ptr<DataTracker> data_tracker_;
  std::unique_ptr<ReassemblyQueue> reasm_;
  std::unique_ptr<RetransmissionQueue> retransmission_queue_;
  std::unique_ptr<StreamResetHandler> handler_;
};

TEST_F(StreamResetHandlerTest, ChunkWithNoParametersReturnsError) {
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  EXPECT_CALL(callbacks_, OnError).Times(1);
  handler_->HandleReConfig(ReConfigChunk(Parameters()));
}

TEST_F(StreamResetHandlerTest, ChunkWithInvalidParametersReturnsError) {
  Parameters::Builder builder;
  // Two OutgoingSSNResetRequestParameter in a RE-CONFIG is not valid.
  builder.Add(OutgoingSSNResetRequestParameter(ReconfigRequestSN(1),
                                               ReconfigRequestSN(10),
                                               kPeerInitialTsn, {StreamID(1)}));
  builder.Add(OutgoingSSNResetRequestParameter(ReconfigRequestSN(2),
                                               ReconfigRequestSN(10),
                                               kPeerInitialTsn, {StreamID(2)}));

  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  EXPECT_CALL(callbacks_, OnError).Times(1);
  handler_->HandleReConfig(ReConfigChunk(builder.Build()));
}

TEST_F(StreamResetHandlerTest, FailToDeliverWithoutResettingStream) {
  reasm_->Add(kPeerInitialTsn, gen_.Ordered({1, 2, 3, 4}, "BE"));
  reasm_->Add(AddTo(kPeerInitialTsn, 1), gen_.Ordered({1, 2, 3, 4}, "BE"));

  data_tracker_->Observe(kPeerInitialTsn);
  data_tracker_->Observe(AddTo(kPeerInitialTsn, 1));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(53), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(53), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());

  gen_.ResetStream();
  reasm_->Add(AddTo(kPeerInitialTsn, 2), gen_.Ordered({1, 2, 3, 4}, "BE"));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetStreamsNotDeferred) {
  reasm_->Add(kPeerInitialTsn, gen_.Ordered({1, 2, 3, 4}, "BE"));
  reasm_->Add(AddTo(kPeerInitialTsn, 1), gen_.Ordered({1, 2, 3, 4}, "BE"));

  data_tracker_->Observe(kPeerInitialTsn);
  data_tracker_->Observe(AddTo(kPeerInitialTsn, 1));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(53), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(53), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());

  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(
      kPeerInitialReqSn, ReconfigRequestSN(3), AddTo(kPeerInitialTsn, 1),
      {StreamID(1)}));

  std::vector<ReconfigurationResponseParameter> responses =
      HandleAndCatchResponse(ReConfigChunk(builder.Build()));
  EXPECT_THAT(responses, SizeIs(1));
  EXPECT_EQ(responses[0].result(), ResponseResult::kSuccessPerformed);

  gen_.ResetStream();
  reasm_->Add(AddTo(kPeerInitialTsn, 2), gen_.Ordered({1, 2, 3, 4}, "BE"));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(53), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetStreamsDeferred) {
  constexpr StreamID kStreamId = StreamID(1);
  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE", {.mid = MID(0)}));

  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE", {.mid = MID(1)}));

  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(53), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(53), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());

  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(13), {kStreamId}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  data_tracker_->Observe(TSN(15));
  reasm_->Add(TSN(15), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.mid = MID(1), .ppid = PPID(5)}));

  data_tracker_->Observe(TSN(14));
  reasm_->Add(TSN(14), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.mid = MID(0), .ppid = PPID(4)}));

  data_tracker_->Observe(TSN(13));
  reasm_->Add(TSN(13), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.mid = MID(3), .ppid = PPID(3)}));

  data_tracker_->Observe(TSN(12));
  reasm_->Add(TSN(12), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.mid = MID(2), .ppid = PPID(2)}));

  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(11), ReconfigRequestSN(4), TSN(13), {kStreamId}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(2), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(3), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(4), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(5), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetStreamsDeferredOnlySelectedStreams) {
  // This test verifies the receiving behavior of receiving messages on
  // streams 1, 2 and 3, and receiving a reset request on stream 1, 2, causing
  // deferred reset processing.

  // Reset stream 1,2 with "last assigned TSN=12"
  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(ReconfigRequestSN(10),
                                               ReconfigRequestSN(3), TSN(12),
                                               {StreamID(1), StreamID(2)}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // TSN 10, SID 1 - before TSN 12 -> deliver
  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(1),
                                     .mid = MID(0),
                                     .ppid = PPID(1001)}));

  // TSN 11, SID 2 - before TSN 12 -> deliver
  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(2),
                                     .mid = MID(0),
                                     .ppid = PPID(1002)}));

  // TSN 12, SID 3 - at TSN 12 -> deliver
  data_tracker_->Observe(TSN(12));
  reasm_->Add(TSN(12), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(3),
                                     .mid = MID(0),
                                     .ppid = PPID(1003)}));

  // TSN 13, SID 1 - after TSN 12 and SID=1 -> defer
  data_tracker_->Observe(TSN(13));
  reasm_->Add(TSN(13), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(1),
                                     .mid = MID(0),
                                     .ppid = PPID(1004)}));

  // TSN 14, SID 2 - after TSN 12 and SID=2 -> defer
  data_tracker_->Observe(TSN(14));
  reasm_->Add(TSN(14), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(2),
                                     .mid = MID(0),
                                     .ppid = PPID(1005)}));

  // TSN 15, SID 3 - after TSN 12, but SID 3 is not reset -> deliver
  data_tracker_->Observe(TSN(15));
  reasm_->Add(TSN(15), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(3),
                                     .mid = MID(1),
                                     .ppid = PPID(1006)}));

  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(1001), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(2), PPID(1002), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(3), PPID(1003), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(3), PPID(1006), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());

  builder.Add(OutgoingSSNResetRequestParameter(ReconfigRequestSN(11),
                                               ReconfigRequestSN(3), TSN(13),
                                               {StreamID(1), StreamID(2)}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(1004), kShortPayload)));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(2), PPID(1005), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetAllStreamsDeferred) {
  // Per RFC 6525 Section 4.1 / 5.2.2 (E3), an empty list of stream numbers in
  // an Outgoing SSN Reset Request parameter indicates that all streams shall be
  // reset.

  // TSN 10 (SSN 0) is received and delivered, advancing Stream 1's expected SSN
  // to 1.
  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(1),
                                     .mid = MID(0),
                                     .ppid = PPID(1001)}));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(1001), kShortPayload)));

  // Receive a reset request for ALL streams (`stream_ids = {}`) with
  // `sender_last_assigned_tsn = 11`. Since TSN 11 has not arrived yet, this
  // enters deferred reset processing.
  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11), {}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // Post-reset message TSN 12 (SSN 0) arrives BEFORE TSN 11. Because it has
  // TSN > 11, it must be deferred until the stream reset is performed.
  data_tracker_->Observe(TSN(12));
  reasm_->Add(TSN(12), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(1),
                                     .mid = MID(0),
                                     .ppid = PPID(1003)}));
  EXPECT_FALSE(reasm_->HasMessages());

  // Now the delayed pre-reset TSN 11 (SSN 1) arrives and is delivered.
  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE",
                                    {.stream_id = StreamID(1),
                                     .mid = MID(1),
                                     .ppid = PPID(1002)}));
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(1002), kShortPayload)));

  // Peer retransmits the reset request now that TSN 11 has been received.
  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11), {}));
  EXPECT_CALL(callbacks_, OnIncomingStreamsReset(IsEmpty()));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  // The deferred post-reset message (TSN 12, SSN 0) should now be reassembled
  // and delivered.
  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(StreamID(1), PPID(1003), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetStreamsDefersForwardTsn) {
  // This test verifies that FORWARD-TSNs are deferred if they want to move
  // the cumulative ack TSN point past sender's last assigned TSN.
  static constexpr StreamID kStreamId = StreamID(42);

  // Simulate sender sends:
  // * TSN 10 (SSN=0, BE, lost),
  // * TSN 11 (SSN=1, BE, lost),
  // * TSN 12 (SSN=2, BE, lost)
  // * RESET THE STREAM
  // * TSN 13 (SSN=0, B, received)
  // * TSN 14 (SSN=0, E, lost),
  // * TSN 15 (SSN=1, BE, received)
  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(12), {kStreamId}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // TSN 13, B, after TSN=12 -> defer
  data_tracker_->Observe(TSN(13));
  reasm_->Add(TSN(13),
              gen_.Ordered(
                  {1, 2, 3, 4}, "B",
                  {.stream_id = kStreamId, .mid = MID(0), .ppid = PPID(1004)}));

  // TSN 15, BE, after TSN=12 -> defer
  data_tracker_->Observe(TSN(15));
  reasm_->Add(TSN(15),
              gen_.Ordered(
                  {1, 2, 3, 4}, "BE",
                  {.stream_id = kStreamId, .mid = MID(1), .ppid = PPID(1005)}));

  // Time passes, sender decides to send FORWARD-TSN up to the RESET.
  data_tracker_->HandleForwardTsn(TSN(12));
  reasm_->HandleForwardTsn(
      TSN(12), std::vector<SkippedStream>({SkippedStream(kStreamId, SSN(2))}));

  // The receiver sends a SACK in response to that. The stream hasn't been
  // reset yet, but the sender now decides that TSN=13-14 is to be skipped.
  // As this has a TSN 14, after TSN=12 -> defer it.
  data_tracker_->HandleForwardTsn(TSN(14));
  reasm_->HandleForwardTsn(
      TSN(14), std::vector<SkippedStream>({SkippedStream(kStreamId, SSN(0))}));

  // Reset the stream -> deferred TSNs should be re-added.
  builder.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(11), ReconfigRequestSN(3), TSN(12), {kStreamId}));
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(builder.Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  EXPECT_THAT(reasm_->GetNextMessage(),
              Optional(SctpMessageIs(kStreamId, PPID(1005), kShortPayload)));
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, SendOutgoingRequestDirectly) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req,
      reconfig->parameters().get<OutgoingSSNResetRequestParameter>());

  EXPECT_EQ(req.request_sequence_number(), kMyInitialReqSn);
  EXPECT_EQ(req.sender_last_assigned_tsn(),
            TSN(*retransmission_queue_->next_tsn() - 1));
  EXPECT_THAT(req.stream_ids(), UnorderedElementsAre(StreamID(42)));
}

TEST_F(StreamResetHandlerTest, ResetMultipleStreamsInOneRequest) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(40)));
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(41)));
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42))).Times(2);
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(43)));
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(44)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));
  handler_->ResetStreams(
      std::vector<StreamID>({StreamID(43), StreamID(44), StreamID(41)}));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42), StreamID(40)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(
          std::vector<StreamID>({StreamID(40), StreamID(41), StreamID(42),
                                 StreamID(43), StreamID(44)})));
  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req,
      reconfig->parameters().get<OutgoingSSNResetRequestParameter>());

  EXPECT_EQ(req.request_sequence_number(), kMyInitialReqSn);
  EXPECT_EQ(req.sender_last_assigned_tsn(),
            TSN(*retransmission_queue_->next_tsn() - 1));
  EXPECT_THAT(req.stream_ids(),
              UnorderedElementsAre(StreamID(40), StreamID(41), StreamID(42),
                                   StreamID(43), StreamID(44)));
}

TEST_F(StreamResetHandlerTest, SendOutgoingRequestDeferred) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset())
      .WillOnce(Return(false))
      .WillOnce(Return(false))
      .WillOnce(Return(true));

  EXPECT_FALSE(handler_->MakeStreamResetRequest().has_value());
  EXPECT_FALSE(handler_->MakeStreamResetRequest().has_value());
  EXPECT_TRUE(handler_->MakeStreamResetRequest().has_value());
}

TEST_F(StreamResetHandlerTest, SendOutgoingResettingOnPositiveResponse) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req,
      reconfig->parameters().get<OutgoingSSNResetRequestParameter>());

  Parameters::Builder builder;
  builder.Add(ReconfigurationResponseParameter(
      req.request_sequence_number(), ResponseResult::kSuccessPerformed));
  ReConfigChunk response_reconfig(builder.Build());

  EXPECT_CALL(producer_, CommitResetStreams);
  EXPECT_CALL(producer_, RollbackResetStreams).Times(0);

  // Processing a response shouldn't result in sending anything.
  EXPECT_CALL(callbacks_, OnError).Times(0);
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  handler_->HandleReConfig(std::move(response_reconfig));
}

TEST_F(StreamResetHandlerTest, SendOutgoingResetRollbackOnError) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req,
      reconfig->parameters().get<OutgoingSSNResetRequestParameter>());

  Parameters::Builder builder;
  builder.Add(ReconfigurationResponseParameter(
      req.request_sequence_number(), ResponseResult::kErrorBadSequenceNumber));
  ReConfigChunk response_reconfig(builder.Build());

  EXPECT_CALL(producer_, CommitResetStreams).Times(0);
  EXPECT_CALL(producer_, RollbackResetStreams);

  // Only requests should result in sending responses.
  EXPECT_CALL(callbacks_, OnError).Times(0);
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  handler_->HandleReConfig(std::move(response_reconfig));
}

TEST_F(StreamResetHandlerTest, SendOutgoingResetRetransmitOnInProgress) {
  static constexpr StreamID kStreamToReset = StreamID(42);

  EXPECT_CALL(producer_, PrepareResetStream(kStreamToReset));
  handler_->ResetStreams(std::vector<StreamID>({kStreamToReset}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({kStreamToReset})));

  std::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig1.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req1,
      reconfig1->parameters().get<OutgoingSSNResetRequestParameter>());

  // Simulate that the peer responded "In Progress".
  Parameters::Builder builder;
  builder.Add(ReconfigurationResponseParameter(req1.request_sequence_number(),
                                               ResponseResult::kInProgress));
  ReConfigChunk response_reconfig(builder.Build());

  EXPECT_CALL(producer_, CommitResetStreams()).Times(0);
  EXPECT_CALL(producer_, RollbackResetStreams()).Times(0);

  // Processing a response shouldn't result in sending anything.
  EXPECT_CALL(callbacks_, OnError).Times(0);
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  handler_->HandleReConfig(std::move(response_reconfig));

  // Let some time pass, so that the reconfig timer expires, and retries the
  // same request.
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(1);
  AdvanceTime(kRto);

  std::vector<uint8_t> payload = callbacks_.ConsumeSentPacket();
  ASSERT_FALSE(payload.empty());

  ASSERT_HAS_VALUE_AND_ASSIGN(SctpPacket packet,
                              SctpPacket::Parse(payload, DcSctpOptions()));
  ASSERT_THAT(packet.descriptors(), SizeIs(1));
  ASSERT_HAS_VALUE_AND_ASSIGN(
      ReConfigChunk reconfig2,
      ReConfigChunk::Parse(packet.descriptors()[0].data));

  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req2,
      reconfig2.parameters().get<OutgoingSSNResetRequestParameter>());

  EXPECT_EQ(req2.request_sequence_number(), req1.request_sequence_number());
  EXPECT_THAT(req2.stream_ids(), UnorderedElementsAre(kStreamToReset));
}

TEST_F(StreamResetHandlerTest,
       SendOutgoingResetRetransmitOnInProgressDoesNotIncrementErrorCounter) {
  static constexpr StreamID kStreamToReset = StreamID(42);

  EXPECT_CALL(producer_, PrepareResetStream(kStreamToReset));
  handler_->ResetStreams(std::vector<StreamID>({kStreamToReset}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({kStreamToReset})));

  std::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig1.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req1,
      reconfig1->parameters().get<OutgoingSSNResetRequestParameter>());

  // Simulate that the peer responded "In Progress".
  Parameters::Builder builder;
  builder.Add(ReconfigurationResponseParameter(req1.request_sequence_number(),
                                               ResponseResult::kInProgress));
  ReConfigChunk response_reconfig(builder.Build());

  // Processing "In Progress" should NOT increment error counter.
  EXPECT_CALL(ctx_, IncrementTxErrorCounter).Times(0);
  handler_->HandleReConfig(std::move(response_reconfig));

  // Timer expires. Should re-send, but NOT increment error counter.
  EXPECT_CALL(ctx_, IncrementTxErrorCounter).Times(0);
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(1);
  AdvanceTime(kRto);
}

TEST_F(StreamResetHandlerTest, ResetWhileRequestIsSentWillQueue) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  std::optional<ReConfigChunk> reconfig1 = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig1.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req1,
      reconfig1->parameters().get<OutgoingSSNResetRequestParameter>());
  EXPECT_EQ(req1.request_sequence_number(), kMyInitialReqSn);
  EXPECT_EQ(req1.sender_last_assigned_tsn(),
            AddTo(retransmission_queue_->next_tsn(), -1));
  EXPECT_THAT(req1.stream_ids(), UnorderedElementsAre(StreamID(42)));

  // Streams reset while the request is in-flight will be queued.
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(41)));
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(43)));
  StreamID stream_ids[] = {StreamID(41), StreamID(43)};
  handler_->ResetStreams(stream_ids);
  EXPECT_EQ(handler_->MakeStreamResetRequest(), std::nullopt);

  Parameters::Builder builder;
  builder.Add(ReconfigurationResponseParameter(
      req1.request_sequence_number(), ResponseResult::kSuccessPerformed));
  ReConfigChunk response_reconfig(builder.Build());

  EXPECT_CALL(producer_, CommitResetStreams()).Times(1);
  EXPECT_CALL(producer_, RollbackResetStreams()).Times(0);

  // Processing a response shouldn't result in sending anything.
  EXPECT_CALL(callbacks_, OnError).Times(0);
  EXPECT_CALL(callbacks_, SendPacketWithStatus).Times(0);
  handler_->HandleReConfig(std::move(response_reconfig));

  // Response has been processed. A new request can be sent.
  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(41), StreamID(43)})));

  std::optional<ReConfigChunk> reconfig2 = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig2.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req2,
      reconfig2->parameters().get<OutgoingSSNResetRequestParameter>());
  EXPECT_EQ(req2.request_sequence_number(), AddTo(kMyInitialReqSn, 1));
  EXPECT_EQ(req2.sender_last_assigned_tsn(),
            TSN(*retransmission_queue_->next_tsn() - 1));
  EXPECT_THAT(req2.stream_ids(),
              UnorderedElementsAre(StreamID(41), StreamID(43)));
}

TEST_F(StreamResetHandlerTest, SendIncomingResetJustReturnsNothingPerformed) {
  Parameters::Builder builder;
  builder.Add(
      IncomingSSNResetRequestParameter(kPeerInitialReqSn, {StreamID(1)}));

  std::vector<ReconfigurationResponseParameter> responses =
      HandleAndCatchResponse(ReConfigChunk(builder.Build()));
  ASSERT_THAT(responses, SizeIs(1));
  EXPECT_THAT(responses[0].response_sequence_number(), kPeerInitialReqSn);
  EXPECT_THAT(responses[0].result(), ResponseResult::kSuccessNothingToDo);
}

TEST_F(StreamResetHandlerTest, SendSameRequestTwiceIsIdempotent) {
  // Simulate that receiving the same chunk twice (due to network issues,
  // or retransmissions, causing a RECONFIG to be re-received) is idempotent.
  for (int i = 0; i < 2; ++i) {
    Parameters::Builder builder;
    builder.Add(OutgoingSSNResetRequestParameter(
        kPeerInitialReqSn, ReconfigRequestSN(3), AddTo(kPeerInitialTsn, 1),
        {StreamID(1)}));

    std::vector<ReconfigurationResponseParameter> responses1 =
        HandleAndCatchResponse(ReConfigChunk(builder.Build()));
    EXPECT_THAT(responses1, SizeIs(1));
    EXPECT_EQ(responses1[0].result(), ResponseResult::kInProgress);
  }
}

TEST_F(StreamResetHandlerTest,
       HandoverIsAllowedOnlyWhenNoStreamIsBeingOrWillBeReset) {
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));
  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_EQ(
      handler_->GetHandoverReadiness(),
      HandoverReadinessStatus(HandoverUnreadinessReason::kPendingStreamReset));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset())
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  ASSERT_TRUE(handler_->MakeStreamResetRequest().has_value());
  EXPECT_EQ(handler_->GetHandoverReadiness(),
            HandoverReadinessStatus(
                HandoverUnreadinessReason::kPendingStreamResetRequest));

  // Reset more streams while the request is in-flight.
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(41)));
  EXPECT_CALL(producer_, PrepareResetStream(StreamID(43)));
  StreamID stream_ids[] = {StreamID(41), StreamID(43)};
  handler_->ResetStreams(stream_ids);

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_EQ(handler_->GetHandoverReadiness(),
            HandoverReadinessStatus()
                .Add(HandoverUnreadinessReason::kPendingStreamResetRequest)
                .Add(HandoverUnreadinessReason::kPendingStreamReset));

  // Processing a response to first request.
  EXPECT_CALL(producer_, CommitResetStreams()).Times(1);
  handler_->HandleReConfig(
      ReConfigChunk(Parameters::Builder()
                        .Add(ReconfigurationResponseParameter(
                            kMyInitialReqSn, ResponseResult::kSuccessPerformed))
                        .Build()));
  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_EQ(
      handler_->GetHandoverReadiness(),
      HandoverReadinessStatus(HandoverUnreadinessReason::kPendingStreamReset));

  // Second request can be sent.
  EXPECT_CALL(producer_, HasStreamsReadyToBeReset())
      .WillOnce(Return(true))
      .WillOnce(Return(false));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(41), StreamID(43)})));

  ASSERT_TRUE(handler_->MakeStreamResetRequest().has_value());
  EXPECT_EQ(handler_->GetHandoverReadiness(),
            HandoverReadinessStatus(
                HandoverUnreadinessReason::kPendingStreamResetRequest));

  // Processing a response to second request.
  EXPECT_CALL(producer_, CommitResetStreams()).Times(1);
  handler_->HandleReConfig(ReConfigChunk(
      Parameters::Builder()
          .Add(ReconfigurationResponseParameter(
              AddTo(kMyInitialReqSn, 1), ResponseResult::kSuccessPerformed))
          .Build()));

  // Seconds response has been processed. No pending resets.
  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(false));

  EXPECT_TRUE(handler_->GetHandoverReadiness().IsReady());
}

TEST_F(StreamResetHandlerTest, HandoverInInitialState) {
  PerformHandover();

  EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
  handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

  EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
  EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
      .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

  std::optional<ReConfigChunk> reconfig = handler_->MakeStreamResetRequest();
  ASSERT_TRUE(reconfig.has_value());
  ASSERT_HAS_VALUE_AND_ASSIGN(
      OutgoingSSNResetRequestParameter req,
      reconfig->parameters().get<OutgoingSSNResetRequestParameter>());

  EXPECT_EQ(req.request_sequence_number(), kMyInitialReqSn);
  EXPECT_EQ(req.sender_last_assigned_tsn(),
            TSN(*retransmission_queue_->next_tsn() - 1));
  EXPECT_THAT(req.stream_ids(), UnorderedElementsAre(StreamID(42)));
}

TEST_F(StreamResetHandlerTest, HandoverAfterHavingResetOneStream) {
  // Reset one stream
  {
    EXPECT_CALL(producer_, PrepareResetStream(StreamID(42)));
    handler_->ResetStreams(std::vector<StreamID>({StreamID(42)}));

    EXPECT_CALL(producer_, HasStreamsReadyToBeReset())
        .WillOnce(Return(true))
        .WillOnce(Return(false));
    EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
        .WillOnce(Return(std::vector<StreamID>({StreamID(42)})));

    ASSERT_HAS_VALUE_AND_ASSIGN(ReConfigChunk reconfig,
                                handler_->MakeStreamResetRequest());
    ASSERT_HAS_VALUE_AND_ASSIGN(
        OutgoingSSNResetRequestParameter req,
        reconfig.parameters().get<OutgoingSSNResetRequestParameter>());
    EXPECT_EQ(req.request_sequence_number(), kMyInitialReqSn);
    EXPECT_EQ(req.sender_last_assigned_tsn(),
              TSN(*retransmission_queue_->next_tsn() - 1));
    EXPECT_THAT(req.stream_ids(), UnorderedElementsAre(StreamID(42)));

    EXPECT_CALL(producer_, CommitResetStreams()).Times(1);
    handler_->HandleReConfig(
        ReConfigChunk(Parameters::Builder()
                          .Add(ReconfigurationResponseParameter(
                              req.request_sequence_number(),
                              ResponseResult::kSuccessPerformed))
                          .Build()));
  }

  PerformHandover();

  // Reset another stream after handover
  {
    EXPECT_CALL(producer_, PrepareResetStream(StreamID(43)));
    handler_->ResetStreams(std::vector<StreamID>({StreamID(43)}));

    EXPECT_CALL(producer_, HasStreamsReadyToBeReset()).WillOnce(Return(true));
    EXPECT_CALL(producer_, GetStreamsReadyToBeReset())
        .WillOnce(Return(std::vector<StreamID>({StreamID(43)})));

    ASSERT_HAS_VALUE_AND_ASSIGN(ReConfigChunk reconfig,
                                handler_->MakeStreamResetRequest());
    ASSERT_HAS_VALUE_AND_ASSIGN(
        OutgoingSSNResetRequestParameter req,
        reconfig.parameters().get<OutgoingSSNResetRequestParameter>());

    EXPECT_EQ(req.request_sequence_number(),
              ReconfigRequestSN(kMyInitialReqSn.value() + 1));
    EXPECT_EQ(req.sender_last_assigned_tsn(),
              TSN(*retransmission_queue_->next_tsn() - 1));
    EXPECT_THAT(req.stream_ids(), UnorderedElementsAre(StreamID(43)));
  }
}

TEST_F(StreamResetHandlerTest, PerformCloseAfterOneFirstFailing) {
  // Inject a stream reset on the first expected TSN (which hasn't been seen).
  Parameters::Builder builder;
  builder.Add(OutgoingSSNResetRequestParameter(
      kPeerInitialReqSn, ReconfigRequestSN(3), kPeerInitialTsn, {StreamID(1)}));

  // The socket is expected to say "in progress" as that TSN hasn't been seen.
  std::vector<ReconfigurationResponseParameter> responses =
      HandleAndCatchResponse(ReConfigChunk(builder.Build()));
  EXPECT_THAT(responses, SizeIs(1));
  EXPECT_EQ(responses[0].result(), ResponseResult::kInProgress);

  // Let the socket receive the TSN.
  DataGeneratorOptions opts;
  opts.mid = MID(0);
  reasm_->Add(kPeerInitialTsn, gen_.Ordered({1, 2, 3, 4}, "BE", opts));
  data_tracker_->Observe(kPeerInitialTsn);

  // And emulate that time has passed, and the peer retries the stream reset,
  // but now with an incremented request sequence number.
  Parameters::Builder builder2;
  builder2.Add(OutgoingSSNResetRequestParameter(
      ReconfigRequestSN(*kPeerInitialReqSn + 1), ReconfigRequestSN(3),
      kPeerInitialTsn, {StreamID(1)}));

  // This is supposed to be handled well.
  std::vector<ReconfigurationResponseParameter> responses2 =
      HandleAndCatchResponse(ReConfigChunk(builder2.Build()));
  EXPECT_THAT(responses2, SizeIs(1));
  EXPECT_EQ(responses2[0].result(), ResponseResult::kSuccessPerformed);
}

TEST_F(StreamResetHandlerTest,
       ResetStreamsDeferredRetransmissionWithSameSeqNumSuccess) {
  // 1. Receive request N -> conditions not met -> respond "In Progress"
  // 2. Conditions met (TSN received)
  // 3. Receive request N (retransmission) -> re-evaluate -> respond "Success"

  constexpr StreamID kStreamId = StreamID(1);

  // Receive 10
  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1, 2, 3, 4}, "BE", {.mid = MID(0)}));

  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(12),
                          {kStreamId}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // Receive 11 and 12 to meet condition.
  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1, 2, 3, 4}, "BE", {.mid = MID(1)}));
  data_tracker_->Observe(TSN(12));
  reasm_->Add(TSN(12), gen_.Ordered({1, 2, 3, 4}, "BE", {.mid = MID(2)}));

  // Peer retransmits the SAME request (SN 10).
  // The handler should re-evaluate, see that TSN 12 is now acked, and perform
  // the reset.
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(12),
                          {kStreamId}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  // Verify streams are actually reset (next message should be on new stream
  // generation).
  EXPECT_THAT(
      reasm_->GetNextMessage(),
      Optional(SctpMessageIs(kStreamId, PPID(53), kShortPayload)));  // TSN 10
  EXPECT_THAT(
      reasm_->GetNextMessage(),
      Optional(SctpMessageIs(kStreamId, PPID(53), kShortPayload)));  // TSN 11
  EXPECT_THAT(
      reasm_->GetNextMessage(),
      Optional(SctpMessageIs(kStreamId, PPID(53), kShortPayload)));  // TSN 12
  EXPECT_FALSE(reasm_->HasMessages());
}

TEST_F(StreamResetHandlerTest, ResetStreamsDeferredWithNewSeqNumSuccess) {
  // Backward compatibility (old behavior):
  // 1. Receive request N -> conditions not met -> respond "In Progress"
  // 2. Conditions met
  // 3. Receive request N+1 -> rreat as new -> respond "Success"

  // Peer asks to reset (Request N=10), waiting for TSN 11.
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // Receive 10 and 11 to meet condition.
  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1}, "BE", {.mid = MID(2)}));
  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1}, "BE", {.mid = MID(1)}));

  // Peer sends NEW request (Request N=11), still waiting for TSN 11.
  // Should accept N+1 as valid and succeed.
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(11), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));
}

TEST_F(StreamResetHandlerTest,
       ResetStreamsDeferredRetransmissionStillInProgress) {
  // 1. Receive Request N -> conditions not met -> respond "In Progress"
  // 2. Conditions STILL not met
  // 3. Receive request N (Retransmission) -> re-evaluate -> respond "In
  // Progress" again

  // First request
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));

  // Retransmission (State has not changed)
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kInProgress)));
}

TEST_F(StreamResetHandlerTest, ResetStreamsSuccessIdempotency) {
  // 1. Receive request N -> conditions met -> respond "Success"
  // 2. Receive request N (Retransmission) -> cached success -> respond
  // "Success"

  data_tracker_->Observe(TSN(10));
  reasm_->Add(TSN(10), gen_.Ordered({1}, "BE", {.mid = MID(1)}));
  data_tracker_->Observe(TSN(11));
  reasm_->Add(TSN(11), gen_.Ordered({1}, "BE", {.mid = MID(1)}));

  // First request: Success
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));

  // Retransmission: Should return cached Success (without performing reset
  // again)
  EXPECT_THAT(HandleAndCatchResponse(ReConfigChunk(
                  Parameters::Builder()
                      .Add(OutgoingSSNResetRequestParameter(
                          ReconfigRequestSN(10), ReconfigRequestSN(3), TSN(11),
                          {StreamID(1)}))
                      .Build())),
              ElementsAre(Property(&ReconfigurationResponseParameter::result,
                                   ResponseResult::kSuccessPerformed)));
}

}  // namespace
}  // namespace dcsctp
