/*
 *  Copyright 2020 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 <memory>
#include <optional>
#include <string>
#include <tuple>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtc_event_log/rtc_event_log_factory.h"
#include "api/rtc_event_log/rtc_event_log_factory_interface.h"
#include "api/rtp_parameters.h"
#include "api/rtp_transceiver_direction.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/task_queue/task_queue_factory.h"
#include "media/base/fake_media_engine.h"
#include "media/base/media_engine.h"
#include "p2p/base/fake_port_allocator.h"
#include "p2p/base/port_allocator.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/session_description.h"
#include "pc/test/enable_fake_media.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/internal/default_socket_server.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/thread.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/scoped_key_value_config.h"

namespace webrtc {

using ::testing::Combine;
using ::testing::ElementsAre;
using ::testing::Field;
using ::testing::Return;
using ::testing::Values;

class PeerConnectionHeaderExtensionTest
    : public ::testing::TestWithParam<
          std::tuple<cricket::MediaType, SdpSemantics>> {
 protected:
  PeerConnectionHeaderExtensionTest()
      : socket_server_(rtc::CreateDefaultSocketServer()),
        main_thread_(socket_server_.get()),
        extensions_(
            {RtpHeaderExtensionCapability("uri1",
                                          1,
                                          RtpTransceiverDirection::kStopped),
             RtpHeaderExtensionCapability("uri2",
                                          2,
                                          RtpTransceiverDirection::kSendOnly),
             RtpHeaderExtensionCapability("uri3",
                                          3,
                                          RtpTransceiverDirection::kRecvOnly),
             RtpHeaderExtensionCapability(
                 "uri4",
                 4,
                 RtpTransceiverDirection::kSendRecv)}) {}

  std::unique_ptr<PeerConnectionWrapper> CreatePeerConnection(
      cricket::MediaType media_type,
      std::optional<SdpSemantics> semantics) {
    auto media_engine = std::make_unique<cricket::FakeMediaEngine>();
    if (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO)
      media_engine->fake_voice_engine()->SetRtpHeaderExtensions(extensions_);
    else
      media_engine->fake_video_engine()->SetRtpHeaderExtensions(extensions_);
    PeerConnectionFactoryDependencies factory_dependencies;
    factory_dependencies.network_thread = rtc::Thread::Current();
    factory_dependencies.worker_thread = rtc::Thread::Current();
    factory_dependencies.signaling_thread = rtc::Thread::Current();
    factory_dependencies.task_queue_factory = CreateDefaultTaskQueueFactory();
    EnableFakeMedia(factory_dependencies, std::move(media_engine));

    factory_dependencies.event_log_factory =
        std::make_unique<RtcEventLogFactory>();

    auto pc_factory =
        CreateModularPeerConnectionFactory(std::move(factory_dependencies));

    auto fake_port_allocator = std::make_unique<cricket::FakePortAllocator>(
        rtc::Thread::Current(),
        std::make_unique<rtc::BasicPacketSocketFactory>(socket_server_.get()),
        &field_trials_);
    auto observer = std::make_unique<MockPeerConnectionObserver>();
    PeerConnectionInterface::RTCConfiguration config;
    if (semantics)
      config.sdp_semantics = *semantics;
    PeerConnectionDependencies pc_dependencies(observer.get());
    pc_dependencies.allocator = std::move(fake_port_allocator);
    auto result = pc_factory->CreatePeerConnectionOrError(
        config, std::move(pc_dependencies));
    EXPECT_TRUE(result.ok());
    observer->SetPeerConnectionInterface(result.value().get());
    return std::make_unique<PeerConnectionWrapper>(
        pc_factory, result.MoveValue(), std::move(observer));
  }

  test::ScopedKeyValueConfig field_trials_;
  std::unique_ptr<rtc::SocketServer> socket_server_;
  rtc::AutoSocketServerThread main_thread_;
  std::vector<RtpHeaderExtensionCapability> extensions_;
};

TEST_P(PeerConnectionHeaderExtensionTest, TransceiverOffersHeaderExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> wrapper =
      CreatePeerConnection(media_type, semantics);
  auto transceiver = wrapper->AddTransceiver(media_type);
  EXPECT_EQ(transceiver->GetHeaderExtensionsToNegotiate(), extensions_);
}

TEST_P(PeerConnectionHeaderExtensionTest,
       SenderReceiverCapabilitiesReturnNotStoppedExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  std::unique_ptr<PeerConnectionWrapper> wrapper =
      CreatePeerConnection(media_type, semantics);
  EXPECT_THAT(wrapper->pc_factory()
                  ->GetRtpSenderCapabilities(media_type)
                  .header_extensions,
              ElementsAre(Field(&RtpHeaderExtensionCapability::uri, "uri2"),
                          Field(&RtpHeaderExtensionCapability::uri, "uri3"),
                          Field(&RtpHeaderExtensionCapability::uri, "uri4")));
  EXPECT_EQ(wrapper->pc_factory()
                ->GetRtpReceiverCapabilities(media_type)
                .header_extensions,
            wrapper->pc_factory()
                ->GetRtpSenderCapabilities(media_type)
                .header_extensions);
}

TEST_P(PeerConnectionHeaderExtensionTest, OffersUnstoppedDefaultExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> wrapper =
      CreatePeerConnection(media_type, semantics);
  auto transceiver = wrapper->AddTransceiver(media_type);
  auto session_description = wrapper->CreateOffer();
  EXPECT_THAT(session_description->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3"),
                          Field(&RtpExtension::uri, "uri4")));
}

TEST_P(PeerConnectionHeaderExtensionTest, OffersUnstoppedModifiedExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> wrapper =
      CreatePeerConnection(media_type, semantics);
  auto transceiver = wrapper->AddTransceiver(media_type);
  auto modified_extensions = transceiver->GetHeaderExtensionsToNegotiate();
  modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
  modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
  EXPECT_TRUE(
      transceiver->SetHeaderExtensionsToNegotiate(modified_extensions).ok());
  auto session_description = wrapper->CreateOffer();
  EXPECT_THAT(session_description->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri1"),
                          Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3")));
}

TEST_P(PeerConnectionHeaderExtensionTest, AnswersUnstoppedModifiedExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc1 =
      CreatePeerConnection(media_type, semantics);
  std::unique_ptr<PeerConnectionWrapper> pc2 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver1 = pc1->AddTransceiver(media_type);

  auto offer = pc1->CreateOfferAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  pc2->SetRemoteDescription(std::move(offer));

  ASSERT_EQ(pc2->pc()->GetTransceivers().size(), 1u);
  auto transceiver2 = pc2->pc()->GetTransceivers()[0];
  auto modified_extensions = transceiver2->GetHeaderExtensionsToNegotiate();
  // Don't offer uri4.
  modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
  transceiver2->SetHeaderExtensionsToNegotiate(modified_extensions);

  auto answer = pc2->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  EXPECT_THAT(answer->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3")));
}

TEST_P(PeerConnectionHeaderExtensionTest, NegotiatedExtensionsAreAccessible) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc1 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver1 = pc1->AddTransceiver(media_type);
  auto modified_extensions = transceiver1->GetHeaderExtensionsToNegotiate();
  modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
  transceiver1->SetHeaderExtensionsToNegotiate(modified_extensions);
  auto offer = pc1->CreateOfferAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());

  std::unique_ptr<PeerConnectionWrapper> pc2 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver2 = pc2->AddTransceiver(media_type);
  pc2->SetRemoteDescription(std::move(offer));
  auto answer = pc2->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  pc1->SetRemoteDescription(std::move(answer));

  // PC1 has exts 2-4 unstopped and PC2 has exts 1-3 unstopped -> ext 2, 3
  // survives.
  EXPECT_THAT(transceiver1->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kStopped)));
}

TEST_P(PeerConnectionHeaderExtensionTest, OfferedExtensionsArePerTransceiver) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc1 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver1 = pc1->AddTransceiver(media_type);
  auto modified_extensions = transceiver1->GetHeaderExtensionsToNegotiate();
  modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
  transceiver1->SetHeaderExtensionsToNegotiate(modified_extensions);
  auto transceiver2 = pc1->AddTransceiver(media_type);

  auto session_description = pc1->CreateOffer();
  EXPECT_THAT(session_description->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3")));
  EXPECT_THAT(session_description->description()
                  ->contents()[1]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3"),
                          Field(&RtpExtension::uri, "uri4")));
}

TEST_P(PeerConnectionHeaderExtensionTest, RemovalAfterRenegotiation) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc1 =
      CreatePeerConnection(media_type, semantics);
  std::unique_ptr<PeerConnectionWrapper> pc2 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver1 = pc1->AddTransceiver(media_type);

  auto offer = pc1->CreateOfferAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  pc2->SetRemoteDescription(std::move(offer));
  auto answer = pc2->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  pc1->SetRemoteDescription(std::move(answer));

  auto modified_extensions = transceiver1->GetHeaderExtensionsToNegotiate();
  modified_extensions[3].direction = RtpTransceiverDirection::kStopped;
  transceiver1->SetHeaderExtensionsToNegotiate(modified_extensions);
  auto session_description = pc1->CreateOffer();
  EXPECT_THAT(session_description->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3")));
}

TEST_P(PeerConnectionHeaderExtensionTest,
       StoppedByDefaultExtensionCanBeActivatedByRemoteSdp) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc1 =
      CreatePeerConnection(media_type, semantics);
  std::unique_ptr<PeerConnectionWrapper> pc2 =
      CreatePeerConnection(media_type, semantics);
  auto transceiver1 = pc1->AddTransceiver(media_type);

  auto offer = pc1->CreateOfferAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  pc2->SetRemoteDescription(std::move(offer));
  auto answer = pc2->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  std::string sdp;
  ASSERT_TRUE(answer->ToString(&sdp));
  // We support uri1 but it is stopped by default. Let the remote reactivate it.
  sdp += "a=extmap:15 uri1\r\n";
  auto modified_answer = CreateSessionDescription(SdpType::kAnswer, sdp);
  pc1->SetRemoteDescription(std::move(modified_answer));
  EXPECT_THAT(transceiver1->GetNegotiatedHeaderExtensions(),
              ElementsAre(Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv),
                          Field(&RtpHeaderExtensionCapability::direction,
                                RtpTransceiverDirection::kSendRecv)));
}

TEST_P(PeerConnectionHeaderExtensionTest,
       UnknownExtensionInRemoteOfferDoesNotShowUp) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc =
      CreatePeerConnection(media_type, semantics);
  std::string sdp =
      "v=0\r\n"
      "o=- 0 3 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=fingerprint:sha-256 "
      "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:"
      "AD:7E:77:43:2A:29:EC:93\r\n"
      "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n"
      "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n";
  if (media_type == cricket::MEDIA_TYPE_AUDIO) {
    sdp +=
        "m=audio 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_audio_codec/8000\r\n";
  } else {
    sdp +=
        "m=video 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_video_codec/90000\r\n";
  }
  sdp +=
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp-mux\r\n"
      "a=sendonly\r\n"
      "a=mid:audio\r\n"
      "a=setup:actpass\r\n"
      "a=extmap:1 urn:bogus\r\n";
  auto offer = CreateSessionDescription(SdpType::kOffer, sdp);
  pc->SetRemoteDescription(std::move(offer));
  pc->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());
  ASSERT_GT(pc->pc()->GetTransceivers().size(), 0u);
  auto transceiver = pc->pc()->GetTransceivers()[0];
  auto negotiated = transceiver->GetNegotiatedHeaderExtensions();
  EXPECT_EQ(negotiated.size(),
            transceiver->GetHeaderExtensionsToNegotiate().size());
  // All extensions are stopped, the "bogus" one does not show up.
  for (const auto& extension : negotiated) {
    EXPECT_EQ(extension.direction, RtpTransceiverDirection::kStopped);
    EXPECT_NE(extension.uri, "urn:bogus");
  }
}

// These tests are regression tests for behavior that the API
// enables in a proper way. It conflicts with the behavior
// of the API to only offer non-stopped extensions.
TEST_P(PeerConnectionHeaderExtensionTest,
       SdpMungingAnswerWithoutApiUsageEnablesExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc =
      CreatePeerConnection(media_type, semantics);
  std::string sdp =
      "v=0\r\n"
      "o=- 0 3 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=fingerprint:sha-256 "
      "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:"
      "AD:7E:77:43:2A:29:EC:93\r\n"
      "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n"
      "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n";
  if (media_type == cricket::MEDIA_TYPE_AUDIO) {
    sdp +=
        "m=audio 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_audio_codec/8000\r\n";
  } else {
    sdp +=
        "m=video 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_video_codec/90000\r\n";
  }
  sdp +=
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp-mux\r\n"
      "a=sendrecv\r\n"
      "a=mid:audio\r\n"
      "a=setup:actpass\r\n"
      "a=extmap:1 uri1\r\n";
  auto offer = CreateSessionDescription(SdpType::kOffer, sdp);
  pc->SetRemoteDescription(std::move(offer));
  auto answer =
      pc->CreateAnswer(PeerConnectionInterface::RTCOfferAnswerOptions());
  std::string modified_sdp;
  ASSERT_TRUE(answer->ToString(&modified_sdp));
  modified_sdp += "a=extmap:1 uri1\r\n";
  auto modified_answer =
      CreateSessionDescription(SdpType::kAnswer, modified_sdp);
  ASSERT_TRUE(pc->SetLocalDescription(std::move(modified_answer)));

  auto session_description = pc->CreateOffer();
  EXPECT_THAT(session_description->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri1"),
                          Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3"),
                          Field(&RtpExtension::uri, "uri4")));
}

TEST_P(PeerConnectionHeaderExtensionTest,
       SdpMungingOfferWithoutApiUsageEnablesExtensions) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc =
      CreatePeerConnection(media_type, semantics);
  pc->AddTransceiver(media_type);

  auto offer =
      pc->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions());
  std::string modified_sdp;
  ASSERT_TRUE(offer->ToString(&modified_sdp));
  modified_sdp += "a=extmap:1 uri1\r\n";
  auto modified_offer = CreateSessionDescription(SdpType::kOffer, modified_sdp);
  ASSERT_TRUE(pc->SetLocalDescription(std::move(modified_offer)));

  auto offer2 =
      pc->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions());
  EXPECT_THAT(offer2->description()
                  ->contents()[0]
                  .media_description()
                  ->rtp_header_extensions(),
              ElementsAre(Field(&RtpExtension::uri, "uri2"),
                          Field(&RtpExtension::uri, "uri3"),
                          Field(&RtpExtension::uri, "uri4"),
                          Field(&RtpExtension::uri, "uri1")));
}

TEST_P(PeerConnectionHeaderExtensionTest, EnablingExtensionsAfterRemoteOffer) {
  cricket::MediaType media_type;
  SdpSemantics semantics;
  std::tie(media_type, semantics) = GetParam();
  if (semantics != SdpSemantics::kUnifiedPlan)
    return;
  std::unique_ptr<PeerConnectionWrapper> pc =
      CreatePeerConnection(media_type, semantics);
  std::string sdp =
      "v=0\r\n"
      "o=- 0 3 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=fingerprint:sha-256 "
      "A7:24:72:CA:6E:02:55:39:BA:66:DF:6E:CC:4C:D8:B0:1A:BF:1A:56:65:7D:F4:03:"
      "AD:7E:77:43:2A:29:EC:93\r\n"
      "a=ice-ufrag:6HHHdzzeIhkE0CKj\r\n"
      "a=ice-pwd:XYDGVpfvklQIEnZ6YnyLsAew\r\n";
  if (media_type == cricket::MEDIA_TYPE_AUDIO) {
    sdp +=
        "m=audio 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_audio_codec/8000\r\n";
  } else {
    sdp +=
        "m=video 9 RTP/AVPF 111\r\n"
        "a=rtpmap:111 fake_video_codec/90000\r\n";
  }
  sdp +=
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp-mux\r\n"
      "a=sendrecv\r\n"
      "a=mid:audio\r\n"
      "a=setup:actpass\r\n"
      "a=extmap:5 uri1\r\n";
  auto offer = CreateSessionDescription(SdpType::kOffer, sdp);
  pc->SetRemoteDescription(std::move(offer));

  ASSERT_GT(pc->pc()->GetTransceivers().size(), 0u);
  auto transceiver = pc->pc()->GetTransceivers()[0];
  auto modified_extensions = transceiver->GetHeaderExtensionsToNegotiate();
  modified_extensions[0].direction = RtpTransceiverDirection::kSendRecv;
  transceiver->SetHeaderExtensionsToNegotiate(modified_extensions);

  pc->CreateAnswerAndSetAsLocal(
      PeerConnectionInterface::RTCOfferAnswerOptions());

  auto session_description = pc->CreateOffer();
  auto extensions = session_description->description()
                        ->contents()[0]
                        .media_description()
                        ->rtp_header_extensions();
  EXPECT_THAT(extensions, ElementsAre(Field(&RtpExtension::uri, "uri1"),
                                      Field(&RtpExtension::uri, "uri2"),
                                      Field(&RtpExtension::uri, "uri3"),
                                      Field(&RtpExtension::uri, "uri4")));
  // Check uri1's id still matches the remote id.
  EXPECT_EQ(extensions[0].id, 5);
}

INSTANTIATE_TEST_SUITE_P(
    ,
    PeerConnectionHeaderExtensionTest,
    Combine(Values(SdpSemantics::kPlanB_DEPRECATED, SdpSemantics::kUnifiedPlan),
            Values(cricket::MediaType::MEDIA_TYPE_AUDIO,
                   cricket::MediaType::MEDIA_TYPE_VIDEO)),
    [](const testing::TestParamInfo<
        PeerConnectionHeaderExtensionTest::ParamType>& info) {
      cricket::MediaType media_type;
      SdpSemantics semantics;
      std::tie(media_type, semantics) = info.param;
      return (rtc::StringBuilder("With")
              << (semantics == SdpSemantics::kPlanB_DEPRECATED ? "PlanB"
                                                               : "UnifiedPlan")
              << "And"
              << (media_type == cricket::MediaType::MEDIA_TYPE_AUDIO ? "Voice"
                                                                     : "Video")
              << "Engine")
          .str();
    });

}  // namespace webrtc
