/*
 *  Copyright 2017 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 check the PeerConnection's signaling state
// machine, as well as tests that check basic, media-agnostic aspects of SDP.

#include <algorithm>
#include <cstdint>
#include <functional>
#include <map>
#include <memory>
#include <set>
#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#include "api/audio/audio_mixer.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/create_peerconnection_factory.h"
#include "api/dtls_transport_interface.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_receiver_interface.h"
#include "api/rtp_sender_interface.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/set_local_description_observer_interface.h"
#include "api/set_remote_description_observer_interface.h"
#include "api/video_codecs/video_decoder_factory_template.h"
#include "api/video_codecs/video_decoder_factory_template_dav1d_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp8_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_decoder_factory_template_open_h264_adapter.h"
#include "api/video_codecs/video_encoder_factory_template.h"
#include "api/video_codecs/video_encoder_factory_template_libaom_av1_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp8_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_libvpx_vp9_adapter.h"
#include "api/video_codecs/video_encoder_factory_template_open_h264_adapter.h"
#include "media/base/codec.h"
#include "modules/audio_device/include/audio_device.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "p2p/base/port_allocator.h"
#include "pc/peer_connection.h"
#include "pc/peer_connection_proxy.h"
#include "pc/peer_connection_wrapper.h"
#include "pc/sdp_utils.h"
#include "pc/session_description.h"
#include "pc/test/mock_peer_connection_observers.h"
#include "rtc_base/checks.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/thread.h"
#include "test/gtest.h"
#ifdef WEBRTC_ANDROID
#include "pc/test/android_test_initializer.h"
#endif
#include "pc/test/fake_audio_capture_module.h"
#include "pc/test/fake_rtc_certificate_generator.h"
#include "rtc_base/gunit.h"
#include "rtc_base/virtual_socket_server.h"

namespace webrtc {

using SignalingState = PeerConnectionInterface::SignalingState;
using RTCConfiguration = PeerConnectionInterface::RTCConfiguration;
using RTCOfferAnswerOptions = PeerConnectionInterface::RTCOfferAnswerOptions;
using ::testing::Bool;
using ::testing::Combine;
using ::testing::Values;

namespace {
const int64_t kWaitTimeout = 10000;
}  // namespace

class PeerConnectionWrapperForSignalingTest : public PeerConnectionWrapper {
 public:
  using PeerConnectionWrapper::PeerConnectionWrapper;

  bool initial_offerer() {
    return GetInternalPeerConnection()->initial_offerer();
  }

  PeerConnection* GetInternalPeerConnection() {
    auto* pci =
        static_cast<PeerConnectionProxyWithInternal<PeerConnectionInterface>*>(
            pc());
    return static_cast<PeerConnection*>(pci->internal());
  }
};

class ExecuteFunctionOnCreateSessionDescriptionObserver
    : public CreateSessionDescriptionObserver {
 public:
  ExecuteFunctionOnCreateSessionDescriptionObserver(
      std::function<void(SessionDescriptionInterface*)> function)
      : function_(std::move(function)) {}
  ~ExecuteFunctionOnCreateSessionDescriptionObserver() override {
    RTC_DCHECK(was_called_);
  }

  bool was_called() const { return was_called_; }

  void OnSuccess(SessionDescriptionInterface* desc) override {
    RTC_DCHECK(!was_called_);
    was_called_ = true;
    function_(desc);
  }

  void OnFailure(RTCError error) override { RTC_DCHECK_NOTREACHED(); }

 private:
  bool was_called_ = false;
  std::function<void(SessionDescriptionInterface*)> function_;
};

class PeerConnectionSignalingBaseTest : public ::testing::Test {
 protected:
  typedef std::unique_ptr<PeerConnectionWrapperForSignalingTest> WrapperPtr;

  explicit PeerConnectionSignalingBaseTest(SdpSemantics sdp_semantics)
      : vss_(new rtc::VirtualSocketServer()),
        main_(vss_.get()),
        sdp_semantics_(sdp_semantics) {
#ifdef WEBRTC_ANDROID
    InitializeAndroidObjects();
#endif
    pc_factory_ = CreatePeerConnectionFactory(
        rtc::Thread::Current(), rtc::Thread::Current(), rtc::Thread::Current(),
        rtc::scoped_refptr<AudioDeviceModule>(FakeAudioCaptureModule::Create()),
        CreateBuiltinAudioEncoderFactory(), CreateBuiltinAudioDecoderFactory(),
        std::make_unique<VideoEncoderFactoryTemplate<
            LibvpxVp8EncoderTemplateAdapter, LibvpxVp9EncoderTemplateAdapter,
            OpenH264EncoderTemplateAdapter, LibaomAv1EncoderTemplateAdapter>>(),
        std::make_unique<VideoDecoderFactoryTemplate<
            LibvpxVp8DecoderTemplateAdapter, LibvpxVp9DecoderTemplateAdapter,
            OpenH264DecoderTemplateAdapter, Dav1dDecoderTemplateAdapter>>(),
        nullptr /* audio_mixer */, nullptr /* audio_processing */);
  }

  WrapperPtr CreatePeerConnection() {
    return CreatePeerConnection(RTCConfiguration());
  }

  WrapperPtr CreatePeerConnection(const RTCConfiguration& config) {
    auto observer = std::make_unique<MockPeerConnectionObserver>();
    RTCConfiguration modified_config = config;
    modified_config.sdp_semantics = sdp_semantics_;
    auto result = pc_factory_->CreatePeerConnectionOrError(
        modified_config, PeerConnectionDependencies(observer.get()));
    if (!result.ok()) {
      return nullptr;
    }

    observer->SetPeerConnectionInterface(result.value().get());
    return std::make_unique<PeerConnectionWrapperForSignalingTest>(
        pc_factory_, result.MoveValue(), std::move(observer));
  }

  // Accepts the same arguments as CreatePeerConnection and adds default audio
  // and video tracks.
  template <typename... Args>
  WrapperPtr CreatePeerConnectionWithAudioVideo(Args&&... args) {
    auto wrapper = CreatePeerConnection(std::forward<Args>(args)...);
    if (!wrapper) {
      return nullptr;
    }
    wrapper->AddAudioTrack("a");
    wrapper->AddVideoTrack("v");
    return wrapper;
  }

  int NumberOfDtlsTransports(const WrapperPtr& pc_wrapper) {
    std::set<DtlsTransportInterface*> transports;
    auto transceivers = pc_wrapper->pc()->GetTransceivers();

    for (auto& transceiver : transceivers) {
      if (transceiver->sender()->dtls_transport()) {
        EXPECT_TRUE(transceiver->receiver()->dtls_transport());
        EXPECT_EQ(transceiver->sender()->dtls_transport().get(),
                  transceiver->receiver()->dtls_transport().get());
        transports.insert(transceiver->sender()->dtls_transport().get());
      } else {
        // If one transceiver is missing, they all should be.
        EXPECT_EQ(0UL, transports.size());
      }
    }
    return transports.size();
  }

  bool HasDtlsTransport(const WrapperPtr& pc_wrapper) {
    return NumberOfDtlsTransports(pc_wrapper) > 0;
  }

  std::unique_ptr<rtc::VirtualSocketServer> vss_;
  rtc::AutoSocketServerThread main_;
  rtc::scoped_refptr<PeerConnectionFactoryInterface> pc_factory_;
  const SdpSemantics sdp_semantics_;
};

class PeerConnectionSignalingTest
    : public PeerConnectionSignalingBaseTest,
      public ::testing::WithParamInterface<SdpSemantics> {
 protected:
  PeerConnectionSignalingTest() : PeerConnectionSignalingBaseTest(GetParam()) {}
};

TEST_P(PeerConnectionSignalingTest, SetLocalOfferTwiceWorks) {
  auto caller = CreatePeerConnection();

  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
  EXPECT_TRUE(caller->SetLocalDescription(caller->CreateOffer()));
}

TEST_P(PeerConnectionSignalingTest, SetRemoteOfferTwiceWorks) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
  EXPECT_TRUE(callee->SetRemoteDescription(caller->CreateOffer()));
}

TEST_P(PeerConnectionSignalingTest, FailToSetNullLocalDescription) {
  auto caller = CreatePeerConnection();
  std::string error;
  ASSERT_FALSE(caller->SetLocalDescription(nullptr, &error));
  EXPECT_EQ("SessionDescription is NULL.", error);
}

TEST_P(PeerConnectionSignalingTest, FailToSetNullRemoteDescription) {
  auto caller = CreatePeerConnection();
  std::string error;
  ASSERT_FALSE(caller->SetRemoteDescription(nullptr, &error));
  EXPECT_EQ("SessionDescription is NULL.", error);
}

// The following parameterized test verifies that calls to various signaling
// methods on PeerConnection will succeed/fail depending on what is the
// PeerConnection's signaling state. Note that the test tries many different
// forms of SignalingState::kClosed by arriving at a valid state then calling
// `Close()`. This is intended to catch cases where the PeerConnection signaling
// method ignores the closed flag but may work/not work because of the single
// state the PeerConnection was created in before it was closed.

class PeerConnectionSignalingStateTest
    : public PeerConnectionSignalingBaseTest,
      public ::testing::WithParamInterface<
          std::tuple<SdpSemantics, SignalingState, bool>> {
 protected:
  PeerConnectionSignalingStateTest()
      : PeerConnectionSignalingBaseTest(std::get<0>(GetParam())),
        state_under_test_(std::make_tuple(std::get<1>(GetParam()),
                                          std::get<2>(GetParam()))) {}

  RTCConfiguration GetConfig() {
    RTCConfiguration config;
    config.certificates.push_back(
        FakeRTCCertificateGenerator::GenerateCertificate());
    return config;
  }

  WrapperPtr CreatePeerConnectionUnderTest() {
    return CreatePeerConnectionInState(state_under_test_);
  }

  WrapperPtr CreatePeerConnectionInState(SignalingState state) {
    return CreatePeerConnectionInState(std::make_tuple(state, false));
  }

  WrapperPtr CreatePeerConnectionInState(
      std::tuple<SignalingState, bool> state_tuple) {
    SignalingState state = std::get<0>(state_tuple);
    bool closed = std::get<1>(state_tuple);

    auto wrapper = CreatePeerConnectionWithAudioVideo(GetConfig());
    switch (state) {
      case SignalingState::kStable: {
        break;
      }
      case SignalingState::kHaveLocalOffer: {
        wrapper->SetLocalDescription(wrapper->CreateOffer());
        break;
      }
      case SignalingState::kHaveLocalPrAnswer: {
        auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
        wrapper->SetRemoteDescription(caller->CreateOffer());
        auto answer = wrapper->CreateAnswer();
        wrapper->SetLocalDescription(
            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
        break;
      }
      case SignalingState::kHaveRemoteOffer: {
        auto caller = CreatePeerConnectionWithAudioVideo(GetConfig());
        wrapper->SetRemoteDescription(caller->CreateOffer());
        break;
      }
      case SignalingState::kHaveRemotePrAnswer: {
        auto callee = CreatePeerConnectionWithAudioVideo(GetConfig());
        callee->SetRemoteDescription(wrapper->CreateOfferAndSetAsLocal());
        auto answer = callee->CreateAnswer();
        wrapper->SetRemoteDescription(
            CloneSessionDescriptionAsType(answer.get(), SdpType::kPrAnswer));
        break;
      }
      case SignalingState::kClosed: {
        RTC_DCHECK_NOTREACHED()
            << "Set the second member of the tuple to true to "
               "achieve a closed state from an existing, valid "
               "state.";
      }
    }

    RTC_DCHECK_EQ(state, wrapper->pc()->signaling_state());

    if (closed) {
      wrapper->pc()->Close();
      RTC_DCHECK_EQ(SignalingState::kClosed, wrapper->signaling_state());
    }

    return wrapper;
  }

  std::tuple<SignalingState, bool> state_under_test_;
};

TEST_P(PeerConnectionSignalingStateTest, CreateOffer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() != SignalingState::kClosed) {
    EXPECT_TRUE(wrapper->CreateOffer());
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->CreateOffer(RTCOfferAnswerOptions(), &error));
    EXPECT_PRED_FORMAT2(AssertStartsWith, error,
                        "CreateOffer called when PeerConnection is closed.");
  }
}

TEST_P(PeerConnectionSignalingStateTest, CreateAnswer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->CreateAnswer());
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->CreateAnswer(RTCOfferAnswerOptions(), &error));
    EXPECT_EQ(error,
              "PeerConnection cannot create an answer in a state other than "
              "have-remote-offer or have-local-pranswer.");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalOffer) {
  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kStable ||
      wrapper->signaling_state() == SignalingState::kHaveLocalOffer) {
    // Need to call CreateOffer on the PeerConnection under test, otherwise when
    // setting the local offer it will want to verify the DTLS fingerprint
    // against the locally generated certificate, but without a call to
    // CreateOffer the certificate will never be generated.
    EXPECT_TRUE(wrapper->SetLocalDescription(wrapper->CreateOffer()));
  } else {
    auto wrapper_for_offer =
        CreatePeerConnectionInState(SignalingState::kHaveLocalOffer);
    auto offer =
        CloneSessionDescription(wrapper_for_offer->pc()->local_description());

    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(offer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set local offer sdp: Called in wrong state:");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalPrAnswer) {
  auto wrapper_for_pranswer =
      CreatePeerConnectionInState(SignalingState::kHaveLocalPrAnswer);
  auto pranswer =
      CloneSessionDescription(wrapper_for_pranswer->pc()->local_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetLocalDescription(std::move(pranswer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(pranswer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set local pranswer sdp: Called in wrong state:");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetLocalAnswer) {
  auto wrapper_for_answer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto answer = wrapper_for_answer->CreateAnswer();

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalPrAnswer ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetLocalDescription(std::move(answer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetLocalDescription(std::move(answer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set local answer sdp: Called in wrong state:");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemoteOffer) {
  auto wrapper_for_offer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto offer =
      CloneSessionDescription(wrapper_for_offer->pc()->remote_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kStable ||
      wrapper->signaling_state() == SignalingState::kHaveRemoteOffer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(offer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(offer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set remote offer sdp: Called in wrong state:");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemotePrAnswer) {
  auto wrapper_for_pranswer =
      CreatePeerConnectionInState(SignalingState::kHaveRemotePrAnswer);
  auto pranswer =
      CloneSessionDescription(wrapper_for_pranswer->pc()->remote_description());

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
      wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(pranswer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(pranswer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set remote pranswer sdp: Called in wrong state:");
  }
}

TEST_P(PeerConnectionSignalingStateTest, SetRemoteAnswer) {
  auto wrapper_for_answer =
      CreatePeerConnectionInState(SignalingState::kHaveRemoteOffer);
  auto answer = wrapper_for_answer->CreateAnswer();

  auto wrapper = CreatePeerConnectionUnderTest();
  if (wrapper->signaling_state() == SignalingState::kHaveLocalOffer ||
      wrapper->signaling_state() == SignalingState::kHaveRemotePrAnswer) {
    EXPECT_TRUE(wrapper->SetRemoteDescription(std::move(answer)));
  } else {
    std::string error;
    ASSERT_FALSE(wrapper->SetRemoteDescription(std::move(answer), &error));
    EXPECT_PRED_FORMAT2(
        AssertStartsWith, error,
        "Failed to set remote answer sdp: Called in wrong state:");
  }
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
                         PeerConnectionSignalingStateTest,
                         Combine(Values(SdpSemantics::kPlanB_DEPRECATED,
                                        SdpSemantics::kUnifiedPlan),
                                 Values(SignalingState::kStable,
                                        SignalingState::kHaveLocalOffer,
                                        SignalingState::kHaveLocalPrAnswer,
                                        SignalingState::kHaveRemoteOffer,
                                        SignalingState::kHaveRemotePrAnswer),
                                 Bool()));

// Test that CreateAnswer fails if a round of offer/answer has been done and
// the PeerConnection is in the stable state.
TEST_P(PeerConnectionSignalingTest, CreateAnswerFailsIfStable) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  ASSERT_TRUE(caller->ExchangeOfferAnswerWith(callee.get()));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
  EXPECT_FALSE(caller->CreateAnswer());

  ASSERT_EQ(SignalingState::kStable, callee->signaling_state());
  EXPECT_FALSE(callee->CreateAnswer());
}

// According to https://tools.ietf.org/html/rfc3264#section-8, the session id
// stays the same but the version must be incremented if a later, different
// session description is generated. These two tests verify that is the case for
// both offers and answers.
TEST_P(PeerConnectionSignalingTest,
       SessionVersionIncrementedInSubsequentDifferentOffer) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  auto original_offer = caller->CreateOfferAndSetAsLocal();
  const std::string original_id = original_offer->session_id();
  const std::string original_version = original_offer->session_version();

  ASSERT_TRUE(callee->SetRemoteDescription(std::move(original_offer)));
  ASSERT_TRUE(caller->SetRemoteDescription(callee->CreateAnswer()));

  // Add track to get a different offer.
  caller->AddAudioTrack("a");

  auto later_offer = caller->CreateOffer();

  EXPECT_EQ(original_id, later_offer->session_id());
  EXPECT_LT(rtc::FromString<uint64_t>(original_version),
            rtc::FromString<uint64_t>(later_offer->session_version()));
}
TEST_P(PeerConnectionSignalingTest,
       SessionVersionIncrementedInSubsequentDifferentAnswer) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  auto original_answer = callee->CreateAnswer();
  const std::string original_id = original_answer->session_id();
  const std::string original_version = original_answer->session_version();

  // Add track to get a different answer.
  callee->AddAudioTrack("a");

  auto later_answer = callee->CreateAnswer();

  EXPECT_EQ(original_id, later_answer->session_id());
  EXPECT_LT(rtc::FromString<uint64_t>(original_version),
            rtc::FromString<uint64_t>(later_answer->session_version()));
}

TEST_P(PeerConnectionSignalingTest, InitiatorFlagSetOnCallerAndNotOnCallee) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  EXPECT_FALSE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());

  ASSERT_TRUE(callee->SetRemoteDescription(caller->CreateOfferAndSetAsLocal()));

  EXPECT_TRUE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());

  ASSERT_TRUE(
      caller->SetRemoteDescription(callee->CreateAnswerAndSetAsLocal()));

  EXPECT_TRUE(caller->initial_offerer());
  EXPECT_FALSE(callee->initial_offerer());
}

// Test creating a PeerConnection, request multiple offers, destroy the
// PeerConnection and make sure we get success/failure callbacks for all of the
// requests.
// Background: crbug.com/507307
TEST_P(PeerConnectionSignalingTest, CreateOffersAndShutdown) {
  auto caller = CreatePeerConnection();

  RTCOfferAnswerOptions options;
  options.offer_to_receive_audio =
      RTCOfferAnswerOptions::kOfferToReceiveMediaTrue;

  rtc::scoped_refptr<MockCreateSessionDescriptionObserver> observers[100];
  for (auto& observer : observers) {
    observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
    caller->pc()->CreateOffer(observer.get(), options);
  }

  // Destroy the PeerConnection.
  caller.reset(nullptr);

  for (auto& observer : observers) {
    // We expect to have received a notification now even if the PeerConnection
    // was terminated. The offer creation may or may not have succeeded, but we
    // must have received a notification.
    EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  }
}

// Similar to the above test, but by closing the PC first the CreateOffer() will
// fail "early", which triggers a codepath where the PeerConnection is
// reponsible for invoking the observer, instead of the normal codepath where
// the WebRtcSessionDescriptionFactory is responsible for it.
TEST_P(PeerConnectionSignalingTest, CloseCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  caller->pc()->Close();
  caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
  caller.reset(nullptr);
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
}

TEST_P(PeerConnectionSignalingTest,
       ImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, ImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(observer);
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       CloseBeforeImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer.get());
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, CloseBeforeImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer);
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       CloseAfterImplicitCreateOfferAndShutdownWithOldObserver) {
  auto caller = CreatePeerConnection();
  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller->pc()->Close();
  caller.reset(nullptr);
  // The old observer does not get invoked because posted messages are lost.
  EXPECT_FALSE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, CloseAfterImplicitCreateOfferAndShutdown) {
  auto caller = CreatePeerConnection();
  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(observer);
  caller->pc()->Close();
  caller.reset(nullptr);
  // The new observer gets invoked because it is called immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_FALSE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       SetLocalDescriptionNewObserverIsInvokedImmediately) {
  auto caller = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto observer = rtc::make_ref_counted<FakeSetLocalDescriptionObserver>();
  caller->pc()->SetLocalDescription(std::move(offer), observer);
  // The new observer is invoked immediately.
  EXPECT_TRUE(observer->called());
  EXPECT_TRUE(observer->error().ok());
}

TEST_P(PeerConnectionSignalingTest,
       SetLocalDescriptionOldObserverIsInvokedInAPostedMessage) {
  auto caller = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get(), offer.release());
  // The old observer is not invoked immediately.
  EXPECT_FALSE(observer->called());
  // Process all currently pending messages by waiting for a posted task to run.
  bool checkpoint_reached = false;
  rtc::Thread::Current()->PostTask(
      [&checkpoint_reached] { checkpoint_reached = true; });
  EXPECT_TRUE_WAIT(checkpoint_reached, kWaitTimeout);
  // If resolving the observer was pending, it must now have been called.
  EXPECT_TRUE(observer->called());
}

TEST_P(PeerConnectionSignalingTest, SetRemoteDescriptionExecutesImmediately) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  // This offer will cause receivers to be created.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // By not waiting for the observer's callback we can verify that the operation
  // executed immediately.
  callee->pc()->SetRemoteDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
  EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
}

TEST_P(PeerConnectionSignalingTest, CreateOfferBlocksSetRemoteDescription) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  // This offer will cause receivers to be created.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
  auto offer_observer =
      rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  // Synchronously invoke CreateOffer() and SetRemoteDescription(). The
  // SetRemoteDescription() operation should be chained to be executed
  // asynchronously, when CreateOffer() completes.
  callee->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
  callee->pc()->SetRemoteDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetRemoteDescriptionObserver>());
  // CreateOffer() is asynchronous; without message processing this operation
  // should not have completed.
  EXPECT_FALSE(offer_observer->called());
  // Due to chaining, the receivers should not have been created by the offer
  // yet.
  EXPECT_EQ(0u, callee->pc()->GetReceivers().size());
  // EXPECT_TRUE_WAIT causes messages to be processed...
  EXPECT_TRUE_WAIT(offer_observer->called(), kWaitTimeout);
  // Now that the offer has been completed, SetRemoteDescription() will have
  // been executed next in the chain.
  EXPECT_EQ(2u, callee->pc()->GetReceivers().size());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCreatesOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());

  // The offer is created asynchronously; message processing is needed for it to
  // complete.
  EXPECT_FALSE(observer->called());
  EXPECT_FALSE(caller->pc()->pending_local_description());
  EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());

  // Wait for messages to be processed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(observer->result());
  EXPECT_TRUE(caller->pc()->pending_local_description());
  EXPECT_EQ(SdpType::kOffer,
            caller->pc()->pending_local_description()->GetType());
  EXPECT_EQ(PeerConnection::kHaveLocalOffer, caller->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCreatesAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  callee->SetRemoteDescription(caller->CreateOffer());
  EXPECT_EQ(PeerConnection::kHaveRemoteOffer, callee->signaling_state());

  auto observer = MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetLocalDescription(observer.get());

  // The answer is created asynchronously; message processing is needed for it
  // to complete.
  EXPECT_FALSE(observer->called());
  EXPECT_FALSE(callee->pc()->current_local_description());

  // Wait for messages to be processed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(observer->result());
  EXPECT_TRUE(callee->pc()->current_local_description());
  EXPECT_EQ(SdpType::kAnswer,
            callee->pc()->current_local_description()->GetType());
  EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionFullExchange) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnectionWithAudioVideo();

  // SetLocalDescription(), implicitly creating an offer.
  auto caller_set_local_description_observer =
      MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(
      caller_set_local_description_observer.get());
  EXPECT_TRUE_WAIT(caller_set_local_description_observer->called(),
                   kWaitTimeout);
  ASSERT_TRUE(caller->pc()->pending_local_description());

  // SetRemoteDescription(offer)
  auto callee_set_remote_description_observer =
      MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetRemoteDescription(
      callee_set_remote_description_observer.get(),
      CloneSessionDescription(caller->pc()->pending_local_description())
          .release());

  // SetLocalDescription(), implicitly creating an answer.
  auto callee_set_local_description_observer =
      MockSetSessionDescriptionObserver::Create();
  callee->pc()->SetLocalDescription(
      callee_set_local_description_observer.get());
  EXPECT_TRUE_WAIT(callee_set_local_description_observer->called(),
                   kWaitTimeout);
  // Chaining guarantees SetRemoteDescription() happened before
  // SetLocalDescription().
  EXPECT_TRUE(callee_set_remote_description_observer->called());
  EXPECT_TRUE(callee->pc()->current_local_description());

  // SetRemoteDescription(answer)
  auto caller_set_remote_description_observer =
      MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetRemoteDescription(
      caller_set_remote_description_observer.get(),
      CloneSessionDescription(callee->pc()->current_local_description())
          .release());
  EXPECT_TRUE_WAIT(caller_set_remote_description_observer->called(),
                   kWaitTimeout);

  EXPECT_EQ(PeerConnection::kStable, caller->signaling_state());
  EXPECT_EQ(PeerConnection::kStable, callee->signaling_state());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCloseBeforeCreatingOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->Close();
  caller->pc()->SetLocalDescription(observer.get());

  // The operation should fail asynchronously.
  EXPECT_FALSE(observer->called());
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_FALSE(observer->result());
  // This did not affect the signaling state.
  EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
  EXPECT_EQ(
      "SetLocalDescription failed to create session description - "
      "SetLocalDescription called when PeerConnection is closed.",
      observer->error());
}

TEST_P(PeerConnectionSignalingTest,
       ParameterlessSetLocalDescriptionCloseWhileCreatingOffer) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  auto observer = MockSetSessionDescriptionObserver::Create();
  caller->pc()->SetLocalDescription(observer.get());
  caller->pc()->Close();

  // The operation should fail asynchronously.
  EXPECT_FALSE(observer->called());
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_FALSE(observer->result());
  // This did not affect the signaling state.
  EXPECT_EQ(PeerConnection::kClosed, caller->pc()->signaling_state());
  EXPECT_EQ(
      "SetLocalDescription failed to create session description - "
      "CreateOffer failed because the session was shut down",
      observer->error());
}

TEST_P(PeerConnectionSignalingTest, UnsupportedContentType) {
  auto caller = CreatePeerConnection();

  // Call setRemoteDescription with a m= line we don't understand.
  std::string sdp =
      "v=0\r\n"
      "o=- 18446744069414584320 18446462598732840960 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=bogus 9 FOO 0 8\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=mid:bogusmid\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  // Assert we respond back with something meaningful.
  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  EXPECT_NE(answer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported(),
            nullptr);
  EXPECT_EQ(answer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported()
                ->media_type(),
            "bogus");
  EXPECT_TRUE(answer->description()->contents()[0].rejected);
  EXPECT_EQ(answer->description()->contents()[0].mid(), "bogusmid");
  EXPECT_EQ(
      answer->description()->contents()[0].media_description()->protocol(),
      "FOO");
  EXPECT_FALSE(
      answer->description()->contents()[0].media_description()->has_codecs());

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));

  // Assert we keep this in susequent offers.
  auto offer = caller->CreateOffer();
  EXPECT_EQ(offer->description()
                ->contents()[0]
                .media_description()
                ->as_unsupported()
                ->media_type(),
            "bogus");
  EXPECT_TRUE(offer->description()->contents()[0].rejected);
  EXPECT_EQ(offer->description()->contents()[0].media_description()->protocol(),
            "FOO");
  EXPECT_EQ(offer->description()->contents()[0].mid(), "bogusmid");
  EXPECT_FALSE(
      offer->description()->contents()[0].media_description()->has_codecs());
  EXPECT_TRUE(caller->SetLocalDescription(std::move(offer)));
}

TEST_P(PeerConnectionSignalingTest, ReceiveFlexFec) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=group:BUNDLE 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102 122\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=rtpmap:122 flexfec-03/90000\r\n"
      "a=fmtp:122 repair-window=10000000\r\n"
      "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
      "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  ASSERT_NE(
      answer->description()->contents()[0].media_description()->as_video(),
      nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->as_video()
                    ->codecs();
  ASSERT_EQ(codecs.size(), 2u);
  EXPECT_EQ(codecs[1].name, "flexfec-03");

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));
}

TEST_P(PeerConnectionSignalingTest, ReceiveFlexFecReoffer) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "a=group:BUNDLE 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102 35\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=rtpmap:35 flexfec-03/90000\r\n"
      "a=fmtp:35 repair-window=10000000\r\n"
      "a=ssrc-group:FEC-FR 1224551896 1953032773\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n"
      "a=ssrc:1953032773 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(caller->SetRemoteDescription(std::move(remote_description)));

  auto answer = caller->CreateAnswer();
  ASSERT_EQ(answer->description()->contents().size(), 1u);
  ASSERT_NE(
      answer->description()->contents()[0].media_description()->as_video(),
      nullptr);
  auto codecs = answer->description()
                    ->contents()[0]
                    .media_description()
                    ->as_video()
                    ->codecs();
  ASSERT_EQ(codecs.size(), 2u);
  EXPECT_EQ(codecs[1].name, "flexfec-03");
  EXPECT_EQ(codecs[1].id, 35);

  EXPECT_TRUE(caller->SetLocalDescription(std::move(answer)));

  // This generates a collision for AV1 which needs to be remapped.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  auto offer_codecs = offer->description()
                          ->contents()[0]
                          .media_description()
                          ->as_video()
                          ->codecs();
  auto flexfec_it = std::find_if(
      offer_codecs.begin(), offer_codecs.end(),
      [](const cricket::Codec& codec) { return codec.name == "flexfec-03"; });
  ASSERT_EQ(flexfec_it->id, 35);
  auto av1_it = std::find_if(
      offer_codecs.begin(), offer_codecs.end(),
      [](const cricket::Codec& codec) { return codec.name == "AV1"; });
  if (av1_it != offer_codecs.end()) {
    ASSERT_NE(av1_it->id, 35);
  }
}

TEST_P(PeerConnectionSignalingTest, MidAttributeMaxLength) {
  auto caller = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      // Too long mid attribute.
      "a=mid:0123456789012345678901234567890123\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_FALSE(caller->SetRemoteDescription(std::move(remote_description)));
}

INSTANTIATE_TEST_SUITE_P(PeerConnectionSignalingTest,
                         PeerConnectionSignalingTest,
                         Values(SdpSemantics::kPlanB_DEPRECATED,
                                SdpSemantics::kUnifiedPlan));

class PeerConnectionSignalingUnifiedPlanTest
    : public PeerConnectionSignalingBaseTest {
 protected:
  PeerConnectionSignalingUnifiedPlanTest()
      : PeerConnectionSignalingBaseTest(SdpSemantics::kUnifiedPlan) {}
};

// We verify that SetLocalDescription() executed immediately by verifying that
// the transceiver mid values got assigned. SLD executing immeditately is not
// unique to Unified Plan, but the transceivers used to verify this are only
// available in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyUsingOldObserver) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // By not waiting for the observer's callback we can verify that the operation
  // executed immediately. The old observer is invoked in a posted message, so
  // waiting for it would not ensure synchronicity.
  RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
  caller->pc()->SetLocalDescription(
      rtc::make_ref_counted<MockSetSessionDescriptionObserver>().get(),
      offer.release());
  EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyUsingNewObserver) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  // Verify that mids were assigned without waiting for the observer. (However,
  // the new observer should also be invoked synchronously - as is ensured by
  // other tests.)
  RTC_DCHECK(!caller->pc()->GetTransceivers()[0]->mid().has_value());
  caller->pc()->SetLocalDescription(
      std::move(offer),
      rtc::make_ref_counted<FakeSetLocalDescriptionObserver>());
  EXPECT_TRUE(caller->pc()->GetTransceivers()[0]->mid().has_value());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SetLocalDescriptionExecutesImmediatelyInsideCreateOfferCallback) {
  auto caller = CreatePeerConnectionWithAudioVideo();

  // This offer will cause transceiver mids to get assigned.
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  auto offer_observer =
      rtc::make_ref_counted<ExecuteFunctionOnCreateSessionDescriptionObserver>(
          [pc = caller->pc()](SessionDescriptionInterface* desc) {
            // By not waiting for the observer's callback we can verify that the
            // operation executed immediately.
            RTC_DCHECK(!pc->GetTransceivers()[0]->mid().has_value());
            pc->SetLocalDescription(
                rtc::make_ref_counted<MockSetSessionDescriptionObserver>()
                    .get(),
                desc);
            EXPECT_TRUE(pc->GetTransceivers()[0]->mid().has_value());
          });
  caller->pc()->CreateOffer(offer_observer.get(), RTCOfferAnswerOptions());
  EXPECT_TRUE_WAIT(offer_observer->was_called(), kWaitTimeout);
}

// Test that transports are shown in the sender/receiver API after offer/answer.
// This only works in Unified Plan.
TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       DtlsTransportsInstantiateInOfferAnswer) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_TRUE(HasDtlsTransport(caller));
  callee->SetRemoteDescription(std::move(offer));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  EXPECT_TRUE(HasDtlsTransport(callee));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_TRUE(HasDtlsTransport(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest, DtlsTransportsMergeWhenBundled) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_EQ(1, NumberOfDtlsTransports(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       DtlsTransportsAreSeparateeWhenUnbundled) {
  auto caller = CreatePeerConnectionWithAudioVideo();
  auto callee = CreatePeerConnection();

  EXPECT_FALSE(HasDtlsTransport(caller));
  EXPECT_FALSE(HasDtlsTransport(callee));
  RTCOfferAnswerOptions unbundle_options;
  unbundle_options.use_rtp_mux = false;
  auto offer = caller->CreateOffer(unbundle_options);
  caller->SetLocalDescription(CloneSessionDescription(offer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));
  callee->SetRemoteDescription(std::move(offer));
  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  callee->SetLocalDescription(CloneSessionDescription(answer.get()));
  EXPECT_EQ(2, NumberOfDtlsTransports(callee));
  caller->SetRemoteDescription(std::move(answer));
  EXPECT_EQ(2, NumberOfDtlsTransports(caller));

  ASSERT_EQ(SignalingState::kStable, caller->signaling_state());
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       ShouldFireNegotiationNeededWhenNoChangesArePending) {
  auto caller = CreatePeerConnection();
  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SuppressNegotiationNeededWhenOperationChainIsNotEmpty) {
  auto caller = CreatePeerConnection();
  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      caller->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());

  auto observer = rtc::make_ref_counted<MockCreateSessionDescriptionObserver>();
  caller->pc()->CreateOffer(observer.get(), RTCOfferAnswerOptions());
  // For this test to work, the operation has to be pending, i.e. the observer
  // has not yet been invoked.
  EXPECT_FALSE(observer->called());
  // Because the Operations Chain is not empty, the event is now suppressed.
  EXPECT_FALSE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
  caller->observer()->clear_latest_negotiation_needed_event();

  // When the Operations Chain becomes empty again, a new negotiation needed
  // event will be generated that is not suppressed.
  EXPECT_TRUE_WAIT(observer->called(), kWaitTimeout);
  EXPECT_TRUE(caller->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(caller->pc()->ShouldFireNegotiationNeededEvent(
      caller->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest,
       SuppressNegotiationNeededWhenSignalingStateIsNotStable) {
  auto caller = CreatePeerConnection();
  auto callee = CreatePeerConnection();
  auto offer = caller->CreateOffer(RTCOfferAnswerOptions());

  EXPECT_FALSE(caller->observer()->has_negotiation_needed_event());
  auto transceiver =
      callee->AddTransceiver(cricket::MEDIA_TYPE_AUDIO, RtpTransceiverInit());
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());

  // Change signaling state (to "have-remote-offer") by setting a remote offer.
  callee->SetRemoteDescription(std::move(offer));
  // Because the signaling state is not "stable", the event is now suppressed.
  EXPECT_FALSE(callee->pc()->ShouldFireNegotiationNeededEvent(
      callee->observer()->latest_negotiation_needed_event()));
  callee->observer()->clear_latest_negotiation_needed_event();

  // Upon rolling back to "stable", a new negotiation needed event will be
  // generated that is not suppressed.
  callee->SetLocalDescription(CreateSessionDescription(SdpType::kRollback, ""));
  EXPECT_TRUE(callee->observer()->has_negotiation_needed_event());
  EXPECT_TRUE(callee->pc()->ShouldFireNegotiationNeededEvent(
      callee->observer()->latest_negotiation_needed_event()));
}

TEST_F(PeerConnectionSignalingUnifiedPlanTest, RtxReofferApt) {
  auto callee = CreatePeerConnection();

  std::string sdp =
      "v=0\r\n"
      "o=- 8403615332048243445 2 IN IP4 127.0.0.1\r\n"
      "s=-\r\n"
      "t=0 0\r\n"
      "m=video 9 UDP/TLS/RTP/SAVPF 102\r\n"
      "c=IN IP4 0.0.0.0\r\n"
      "a=rtcp:9 IN IP4 0.0.0.0\r\n"
      "a=ice-ufrag:IZeV\r\n"
      "a=ice-pwd:uaZhQD4rYM/Tta2qWBT1Bbt4\r\n"
      "a=ice-options:trickle\r\n"
      "a=fingerprint:sha-256 "
      "D8:6C:3D:FA:23:E2:2C:63:11:2D:D0:86:BE:C4:D0:65:F9:42:F7:1C:06:04:27:E6:"
      "1C:2C:74:01:8D:50:67:23\r\n"
      "a=setup:actpass\r\n"
      "a=mid:0\r\n"
      "a=sendrecv\r\n"
      "a=msid:stream track\r\n"
      "a=rtcp-mux\r\n"
      "a=rtcp-rsize\r\n"
      "a=rtpmap:102 VP8/90000\r\n"
      "a=rtcp-fb:102 goog-remb\r\n"
      "a=rtcp-fb:102 transport-cc\r\n"
      "a=rtcp-fb:102 ccm fir\r\n"
      "a=rtcp-fb:102 nack\r\n"
      "a=rtcp-fb:102 nack pli\r\n"
      "a=ssrc:1224551896 cname:/exJcmhSLpyu9FgV\r\n";
  std::unique_ptr<SessionDescriptionInterface> remote_description =
      CreateSessionDescription(SdpType::kOffer, sdp, nullptr);

  EXPECT_TRUE(callee->SetRemoteDescription(std::move(remote_description)));

  auto answer = callee->CreateAnswer(RTCOfferAnswerOptions());
  EXPECT_TRUE(
      callee->SetLocalDescription(CloneSessionDescription(answer.get())));

  callee->pc()->GetTransceivers()[0]->StopStandard();
  auto reoffer = callee->CreateOffer(RTCOfferAnswerOptions());
  auto codecs = reoffer->description()
                    ->contents()[0]
                    .media_description()
                    ->as_video()
                    ->codecs();
  ASSERT_GT(codecs.size(), 2u);
  EXPECT_EQ(codecs[0].name, "VP8");
  EXPECT_EQ(codecs[1].name, "rtx");
  auto apt_it = codecs[1].params.find("apt");
  ASSERT_NE(apt_it, codecs[1].params.end());
  // The apt should match the id from the remote offer.
  EXPECT_EQ(apt_it->second, rtc::ToString(codecs[0].id));
  EXPECT_EQ(apt_it->second, "102");
}

}  // namespace webrtc
