/*
 *  Copyright 2024 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.
 */

// This file contains tests that verify that congestion control options
// are correctly negotiated in the SDP offer/answer.

#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "absl/strings/str_cat.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtp_parameters.h"
#include "api/rtp_transceiver_direction.h"
#include "api/test/rtc_error_matchers.h"
#include "pc/session_description.h"
#include "pc/test/integration_test_helpers.h"
#include "system_wrappers/include/metrics.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

namespace webrtc {

using ::testing::ContainsRegex;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Gt;
using ::testing::HasSubstr;
using ::testing::IsTrue;
using ::testing::Not;

class PeerConnectionCongestionControlTest
    : public PeerConnectionIntegrationBaseTest {
 public:
  PeerConnectionCongestionControlTest()
      : PeerConnectionIntegrationBaseTest(SdpSemantics::kUnifiedPlan) {}
};

// This regexp matches both wildcard and non-wildcard ccfb lines.
constexpr std::string_view ccfb_regex = "a=rtcp-fb:[0-9*]* ack ccfb\r\n";

TEST_F(PeerConnectionCongestionControlTest,
       OfferDoesNotContainCcfbEvenIfEnabled) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  caller()->AddAudioVideoTracks();
  std::unique_ptr<SessionDescriptionInterface> offer =
      caller()->CreateOfferAndWait();
  std::string offer_str = absl::StrCat(*offer);
  EXPECT_THAT(offer_str, Not(ContainsRegex(ccfb_regex)));
}

TEST_F(PeerConnectionCongestionControlTest, OfferContainsCcfbIfFieldTrial) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  caller()->AddAudioVideoTracks();
  std::unique_ptr<SessionDescriptionInterface> offer =
      caller()->CreateOfferAndWait();
  std::string offer_str = absl::StrCat(*offer);
  EXPECT_THAT(offer_str, ContainsRegex(ccfb_regex));
}

TEST_F(PeerConnectionCongestionControlTest, ReceiveOfferSetsCcfbFlag) {
  SetFieldTrials(kCallerName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  SetFieldTrials(kCalleeName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  {
    // Check that the callee parsed it.
    auto parsed_contents =
        callee()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    for (const auto& content : parsed_contents) {
      EXPECT_TRUE(content.media_description()->rtcp_fb_ack_ccfb());
    }
  }

  {
    // Check that the caller also parsed it.
    auto parsed_contents =
        caller()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    for (const auto& content : parsed_contents) {
      EXPECT_TRUE(content.media_description()->rtcp_fb_ack_ccfb());
    }
  }
  // Check that the answer does not contain transport-cc
  std::string answer_str = absl::StrCat(*caller()->pc()->remote_description());
  EXPECT_THAT(answer_str, Not(HasSubstr("transport-cc")));
}

TEST_F(PeerConnectionCongestionControlTest, SendOnlySupportDoesNotEnableCcFb) {
  // Enable CCFB for sender, do not enable it for receiver
  SetFieldTrials(kCallerName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  SetFieldTrials(kCalleeName,
                 "WebRTC-RFC8888CongestionControlFeedback/Disabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  {
    // Check that the callee parsed the CCFB
    auto parsed_contents =
        callee()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    for (const auto& content : parsed_contents) {
      EXPECT_TRUE(content.media_description()->rtcp_fb_ack_ccfb());
    }
  }

  {
    // Check that the caller did NOT get ccfb in response
    auto parsed_contents =
        caller()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    for (const auto& content : parsed_contents) {
      EXPECT_FALSE(content.media_description()->rtcp_fb_ack_ccfb());
    }
  }
  // Check that the answer does contain transport-cc
  std::string answer_str = absl::StrCat(*caller()->pc()->remote_description());
  EXPECT_THAT(answer_str, HasSubstr("transport-cc"));
}

TEST_F(PeerConnectionCongestionControlTest,
       ReNegotiationCalleeDoesNotSupportCcfb) {
  // Enable CCFB for sender, do not enable it for receiver
  SetFieldTrials(kCallerName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  SetFieldTrials(kCalleeName,
                 "WebRTC-RFC8888CongestionControlFeedback/Disabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));

  // Check that the callee answer does contain transport-cc
  std::string answer_str = absl::StrCat(*caller()->pc()->remote_description());
  ASSERT_THAT(answer_str, HasSubstr("transport-cc"));

  // Callee re-negotiates
  callee()->AddVideoTrack();
  callee()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  // Check that the caller's answer does contain CCFB.
  answer_str = absl::StrCat(*caller()->pc()->local_description());
  EXPECT_THAT(answer_str, Not(HasSubstr("ccfb")));
}

TEST_F(PeerConnectionCongestionControlTest, ReNegotiationBothSupportCcfb) {
  SetFieldTrials(kCallerName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"
                 "WebRTC-HeaderExtensionNegotiateMemory/Enabled/");
  SetFieldTrials(kCalleeName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"
                 "WebRTC-HeaderExtensionNegotiateMemory/Enabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));

  // Check that the callee's answer does  not contain transport-cc
  std::string answer_str = absl::StrCat(*caller()->pc()->remote_description());
  ASSERT_THAT(answer_str, Not(HasSubstr("transport-cc")));

  // Callee re-negotiates
  callee()->AddVideoTrack();
  callee()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  std::string offer_str = absl::StrCat(*callee()->pc()->local_description());
  EXPECT_THAT(offer_str, Not(HasSubstr("transport-cc")));
  EXPECT_THAT(
      offer_str,
      Not(HasSubstr("http://www.ietf.org/id/"
                    "draft-holmer-rmcat-transport-wide-cc-extensions-01")));

  answer_str = absl::StrCat(*caller()->pc()->local_description());
  EXPECT_THAT(answer_str, Not(HasSubstr("transport-cc")));
  EXPECT_THAT(
      answer_str,
      Not(HasSubstr("http://www.ietf.org/id/"
                    "draft-holmer-rmcat-transport-wide-cc-extensions-01")));
}

#ifdef WEBRTC_HAVE_SCTP
TEST_F(PeerConnectionCongestionControlTest,
       ReceiveOfferWithDataChannelsSetsCcfbFlag) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  caller()->AddAudioVideoTracks();
  caller()->CreateDataChannel();
  callee()->CreateDataChannel();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  {
    // Check that the callee parsed it.
    auto parsed_contents =
        callee()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    bool has_data_channel = false;
    for (const auto& content : parsed_contents) {
      if (content.type == MediaProtocolType::kSctp) {
        EXPECT_FALSE(content.media_description()->rtcp_fb_ack_ccfb());
        has_data_channel = true;
      } else {
        EXPECT_TRUE(content.media_description()->rtcp_fb_ack_ccfb());
      }
    }
    ASSERT_TRUE(has_data_channel);
  }

  {
    // Check that the caller also parsed the answer.
    auto parsed_contents =
        caller()->pc()->remote_description()->description()->contents();
    EXPECT_FALSE(parsed_contents.empty());
    bool has_data_channel = false;
    for (const auto& content : parsed_contents) {
      if (content.type == MediaProtocolType::kSctp) {
        EXPECT_FALSE(content.media_description()->rtcp_fb_ack_ccfb());
        has_data_channel = true;
      } else {
        EXPECT_TRUE(content.media_description()->rtcp_fb_ack_ccfb());
      }
    }
    ASSERT_TRUE(has_data_channel);
  }
  // Check that the answer does not contain transport-cc
  std::string answer_str = absl::StrCat(*caller()->pc()->remote_description());
  EXPECT_THAT(answer_str, Not(HasSubstr("transport-cc")));
}
#endif

TEST_F(PeerConnectionCongestionControlTest, NegotiatingCcfbRemovesTsn) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignalingForSdpOnly();
  callee()->AddVideoTrack();
  callee()->AddAudioTrack();
  // Add transceivers to caller in order to accomodate reception
  caller()->pc()->AddTransceiver(MediaType::VIDEO);
  caller()->pc()->AddTransceiver(MediaType::AUDIO);

  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));

  ASSERT_THAT(caller()->pc()->GetTransceivers().size(), Eq(2));
  EXPECT_THAT(
      caller()->pc()->GetTransceivers()[0]->GetNegotiatedHeaderExtensions(),
      Not(Contains(
          AllOf(Field("uri", &RtpHeaderExtensionCapability::uri,
                      RtpExtension::kTransportSequenceNumberUri),
                Not(Field("direction", &RtpHeaderExtensionCapability::direction,
                          RtpTransceiverDirection::kStopped))))))
      << " in caller negotiated header extensions";
  EXPECT_THAT(
      caller()->pc()->GetTransceivers()[1]->GetNegotiatedHeaderExtensions(),
      Not(Contains(
          AllOf(Field("uri", &RtpHeaderExtensionCapability::uri,
                      RtpExtension::kTransportSequenceNumberUri),
                Not(Field("direction", &RtpHeaderExtensionCapability::direction,
                          RtpTransceiverDirection::kStopped))))))
      << " in caller negotiated header extensions";

  ASSERT_THAT(caller()->pc()->GetSenders().size(), Eq(2));
  EXPECT_THAT(
      caller()->pc()->GetSenders()[0]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in caller sender parameters";
  EXPECT_THAT(
      caller()->pc()->GetSenders()[1]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in caller sender parameters";
  EXPECT_THAT(
      caller()->pc()->GetReceivers()[0]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in caller receiver parameters";
  EXPECT_THAT(caller()->pc()->GetReceivers()[1]->media_type(),
              Eq(MediaType::AUDIO));
  EXPECT_THAT(
      caller()->pc()->GetReceivers()[1]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in caller receiver parameters";

  EXPECT_THAT(
      callee()->pc()->GetSenders()[0]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in callee sender parameters";
  EXPECT_THAT(
      callee()->pc()->GetSenders()[1]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in callee sender parameters";

  ASSERT_THAT(callee()->pc()->GetReceivers().size(), Eq(2));
  EXPECT_THAT(
      callee()->pc()->GetReceivers()[0]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in callee receiver parameters";
  EXPECT_THAT(
      callee()->pc()->GetReceivers()[1]->GetParameters().header_extensions,
      Not(Contains(Field("uri", &RtpExtension::uri,
                         RtpExtension::kTransportSequenceNumberUri))))
      << " in callee receiver parameters";
}

TEST_F(PeerConnectionCongestionControlTest, CcfbGetsUsed) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  MediaExpectations media_expectations;
  media_expectations.CalleeExpectsSomeAudio();
  media_expectations.CalleeExpectsSomeVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
  auto pc_internal = caller()->pc_internal();
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return pc_internal->FeedbackAccordingToRfc8888CountForTesting();
          },
          Gt(0)),
      IsRtcOk());
  // There should be no transport-cc generated.
  EXPECT_THAT(pc_internal->FeedbackAccordingToTransportCcCountForTesting(),
              Eq(0));
}

TEST_F(PeerConnectionCongestionControlTest, CcfbGetsUsedWithPrAnswer) {
  // CCFB negotiation is asymmetric: the generator sets the flag but doesn't
  // add it to codecs' feedback_params, while the parser adds it to codecs'
  // feedback_params. This causes false positive munging detection (71, 86)
  // when the prAnswer is re-parsed.
  SetFieldTrials(
      "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/"
      "WebRTC-NoSdpMangleAllowForTesting/Enabled,71,86/");
  metrics::Reset();
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->AddAudioVideoTracks();
  callee()->SetGeneratedSdpMunger(
      [](std::unique_ptr<SessionDescriptionInterface>& sdp) {
        SetSdpType(sdp, SdpType::kPrAnswer);
      });
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] {
    return caller()->pc()->signaling_state() ==
           PeerConnectionInterface::kHaveRemotePrAnswer;
  }));
  MediaExpectations media_expectations;
  media_expectations.CalleeExpectsSomeAudio();
  media_expectations.CalleeExpectsSomeVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
  auto pc_internal = caller()->pc_internal();
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return pc_internal->FeedbackAccordingToRfc8888CountForTesting();
          },
          Gt(0)),
      IsRtcOk());
  // There should be no transport-cc generated.
  EXPECT_THAT(pc_internal->FeedbackAccordingToTransportCcCountForTesting(),
              Eq(0));
  // Note that metrics are picked up from both PCs, so the number
  // of metric counts is 2.
  EXPECT_METRIC_EQ(
      metrics::NumSamples("WebRTC.PeerConnection.NegotiatedFeedbackType"), 2);
  EXPECT_METRIC_EQ(
      metrics::NumEvents("WebRTC.PeerConnection.NegotiatedFeedbackType",
                         static_cast<int>(RtcpFeedbackType::CCFB)),
      2);
  EXPECT_METRIC_EQ(
      metrics::NumEvents("WebRTC.PeerConnection.NegotiatedFeedbackType",
                         static_cast<int>(RtcpFeedbackType::TRANSPORT_CC)),
      0);
}

TEST_F(PeerConnectionCongestionControlTest, TransportCcGetsUsed) {
  SetFieldTrials("WebRTC-RFC8888CongestionControlFeedback/Disabled/");
  metrics::Reset();
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  MediaExpectations media_expectations;
  media_expectations.CalleeExpectsSomeAudio();
  media_expectations.CalleeExpectsSomeVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
  auto pc_internal = caller()->pc_internal();
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return pc_internal->FeedbackAccordingToTransportCcCountForTesting();
          },
          Gt(0)),
      IsRtcOk());
  // Test that RFC 8888 feedback is NOT generated when field trial disabled.
  EXPECT_THAT(pc_internal->FeedbackAccordingToRfc8888CountForTesting(), Eq(0));
  // Note that metrics are picked up from both PCs, so the number
  // of metric counts is 2.
  EXPECT_METRIC_EQ(
      metrics::NumSamples("WebRTC.PeerConnection.NegotiatedFeedbackType"), 2);
  EXPECT_METRIC_EQ(
      metrics::NumEvents("WebRTC.PeerConnection.NegotiatedFeedbackType",
                         static_cast<int>(RtcpFeedbackType::CCFB)),
      0);
  EXPECT_METRIC_EQ(
      metrics::NumEvents("WebRTC.PeerConnection.NegotiatedFeedbackType",
                         static_cast<int>(RtcpFeedbackType::TRANSPORT_CC)),
      2);
}

TEST_F(PeerConnectionCongestionControlTest,
       TransportCcGetsUsedIfCalleeNotEnabledRfc8888) {
  SetFieldTrials(kCallerName,
                 "WebRTC-RFC8888CongestionControlFeedback/Enabled,offer:true/");
  SetFieldTrials(kCalleeName,
                 "WebRTC-RFC8888CongestionControlFeedback/Disabled/");
  ASSERT_TRUE(CreatePeerConnectionWrappers());
  ConnectFakeSignaling();
  caller()->AddAudioVideoTracks();
  caller()->CreateAndSetAndSignalOffer();
  ASSERT_TRUE(WaitUntil([&] { return SignalingStateStable(); }));
  MediaExpectations media_expectations;
  media_expectations.CalleeExpectsSomeAudio();
  media_expectations.CalleeExpectsSomeVideo();
  ASSERT_TRUE(ExpectNewFrames(media_expectations));
  auto pc_internal = caller()->pc_internal();
  EXPECT_THAT(
      WaitUntil(
          [&] {
            return pc_internal->FeedbackAccordingToTransportCcCountForTesting();
          },
          Gt(0)),
      IsRtcOk());
  // Test that RFC 8888 feedback is NOT generated when field trial disabled.
  EXPECT_THAT(pc_internal->FeedbackAccordingToRfc8888CountForTesting(), Eq(0));
}

}  // namespace webrtc
