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

#include <memory>
#include <utility>  // For std::pair, std::move.

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/ortc/ortcfactoryinterface.h"
#include "ortc/testrtpparameters.h"
#include "p2p/base/udptransport.h"
#include "pc/test/fakeaudiocapturemodule.h"
#include "pc/test/fakeperiodicvideotracksource.h"
#include "pc/test/fakevideotrackrenderer.h"
#include "pc/videotracksource.h"
#include "rtc_base/criticalsection.h"
#include "rtc_base/fakenetwork.h"
#include "rtc_base/gunit.h"
#include "rtc_base/virtualsocketserver.h"

namespace {

const int kDefaultTimeout = 10000;    // 10 seconds.
const int kReceivingDuration = 1000;  // 1 second.

// Default number of audio/video frames to wait for before considering a test a
// success.
const int kDefaultNumFrames = 3;
const rtc::IPAddress kIPv4LocalHostAddress =
    rtc::IPAddress(0x7F000001);  // 127.0.0.1

static const char kTestKeyParams1[] =
    "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVz";
static const char kTestKeyParams2[] =
    "inline:PS1uQCVeeCFCanVmcjkpaywjNWhcYD0mXXtxaVBR";
static const char kTestKeyParams3[] =
    "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVa";
static const char kTestKeyParams4[] =
    "inline:WVNfX19zZW1jdGwgKskgewkyMjA7fQp9CnVubGVb";
static const cricket::CryptoParams kTestCryptoParams1(1,
                                                      "AES_CM_128_HMAC_SHA1_80",
                                                      kTestKeyParams1,
                                                      "");
static const cricket::CryptoParams kTestCryptoParams2(1,
                                                      "AES_CM_128_HMAC_SHA1_80",
                                                      kTestKeyParams2,
                                                      "");
static const cricket::CryptoParams kTestCryptoParams3(1,
                                                      "AES_CM_128_HMAC_SHA1_80",
                                                      kTestKeyParams3,
                                                      "");
static const cricket::CryptoParams kTestCryptoParams4(1,
                                                      "AES_CM_128_HMAC_SHA1_80",
                                                      kTestKeyParams4,
                                                      "");
}  // namespace

namespace webrtc {

// Used to test that things work end-to-end when using the default
// implementations of threads/etc. provided by OrtcFactory, with the exception
// of using a virtual network.
//
// By default, the virtual network manager doesn't enumerate any networks, but
// sockets can still be created in this state.
class OrtcFactoryIntegrationTest : public testing::Test {
 public:
  OrtcFactoryIntegrationTest()
      : network_thread_(&virtual_socket_server_),
        fake_audio_capture_module1_(FakeAudioCaptureModule::Create()),
        fake_audio_capture_module2_(FakeAudioCaptureModule::Create()) {
    // Sockets are bound to the ANY address, so this is needed to tell the
    // virtual network which address to use in this case.
    virtual_socket_server_.SetDefaultRoute(kIPv4LocalHostAddress);
    network_thread_.SetName("TestNetworkThread", this);
    network_thread_.Start();
    // Need to create after network thread is started.
    ortc_factory1_ =
        OrtcFactoryInterface::Create(
            &network_thread_, nullptr, &fake_network_manager_, nullptr,
            fake_audio_capture_module1_, CreateBuiltinAudioEncoderFactory(),
            CreateBuiltinAudioDecoderFactory())
            .MoveValue();
    ortc_factory2_ =
        OrtcFactoryInterface::Create(
            &network_thread_, nullptr, &fake_network_manager_, nullptr,
            fake_audio_capture_module2_, CreateBuiltinAudioEncoderFactory(),
            CreateBuiltinAudioDecoderFactory())
            .MoveValue();
  }

 protected:
  typedef std::pair<std::unique_ptr<UdpTransportInterface>,
                    std::unique_ptr<UdpTransportInterface>>
      UdpTransportPair;
  typedef std::pair<std::unique_ptr<RtpTransportInterface>,
                    std::unique_ptr<RtpTransportInterface>>
      RtpTransportPair;
  typedef std::pair<std::unique_ptr<SrtpTransportInterface>,
                    std::unique_ptr<SrtpTransportInterface>>
      SrtpTransportPair;
  typedef std::pair<std::unique_ptr<RtpTransportControllerInterface>,
                    std::unique_ptr<RtpTransportControllerInterface>>
      RtpTransportControllerPair;

  // Helper function that creates one UDP transport each for |ortc_factory1_|
  // and |ortc_factory2_|, and connects them.
  UdpTransportPair CreateAndConnectUdpTransportPair() {
    auto transport1 = ortc_factory1_->CreateUdpTransport(AF_INET).MoveValue();
    auto transport2 = ortc_factory2_->CreateUdpTransport(AF_INET).MoveValue();
    transport1->SetRemoteAddress(
        rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
                           transport2->GetLocalAddress().port()));
    transport2->SetRemoteAddress(
        rtc::SocketAddress(virtual_socket_server_.GetDefaultRoute(AF_INET),
                           transport1->GetLocalAddress().port()));
    return {std::move(transport1), std::move(transport2)};
  }

  // Creates one transport controller each for |ortc_factory1_| and
  // |ortc_factory2_|.
  RtpTransportControllerPair CreateRtpTransportControllerPair() {
    return {ortc_factory1_->CreateRtpTransportController().MoveValue(),
            ortc_factory2_->CreateRtpTransportController().MoveValue()};
  }

  // Helper function that creates a pair of RtpTransports between
  // |ortc_factory1_| and |ortc_factory2_|. Expected to be called with the
  // result of CreateAndConnectUdpTransportPair. |rtcp_udp_transports| can be
  // empty if RTCP muxing is used. |transport_controllers| can be empty if
  // these transports are being created using a default transport controller.
  RtpTransportPair CreateRtpTransportPair(
      const RtpTransportParameters& parameters,
      const UdpTransportPair& rtp_udp_transports,
      const UdpTransportPair& rtcp_udp_transports,
      const RtpTransportControllerPair& transport_controllers) {
    auto transport_result1 = ortc_factory1_->CreateRtpTransport(
        parameters, rtp_udp_transports.first.get(),
        rtcp_udp_transports.first.get(), transport_controllers.first.get());
    auto transport_result2 = ortc_factory2_->CreateRtpTransport(
        parameters, rtp_udp_transports.second.get(),
        rtcp_udp_transports.second.get(), transport_controllers.second.get());
    return {transport_result1.MoveValue(), transport_result2.MoveValue()};
  }

  SrtpTransportPair CreateSrtpTransportPair(
      const RtpTransportParameters& parameters,
      const UdpTransportPair& rtp_udp_transports,
      const UdpTransportPair& rtcp_udp_transports,
      const RtpTransportControllerPair& transport_controllers) {
    auto transport_result1 = ortc_factory1_->CreateSrtpTransport(
        parameters, rtp_udp_transports.first.get(),
        rtcp_udp_transports.first.get(), transport_controllers.first.get());
    auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
        parameters, rtp_udp_transports.second.get(),
        rtcp_udp_transports.second.get(), transport_controllers.second.get());
    return {transport_result1.MoveValue(), transport_result2.MoveValue()};
  }

  // For convenience when |rtcp_udp_transports| and |transport_controllers|
  // aren't needed.
  RtpTransportPair CreateRtpTransportPair(
      const RtpTransportParameters& parameters,
      const UdpTransportPair& rtp_udp_transports) {
    return CreateRtpTransportPair(parameters, rtp_udp_transports,
                                  UdpTransportPair(),
                                  RtpTransportControllerPair());
  }

  SrtpTransportPair CreateSrtpTransportPairAndSetKeys(
      const RtpTransportParameters& parameters,
      const UdpTransportPair& rtp_udp_transports) {
    SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
        parameters, rtp_udp_transports, UdpTransportPair(),
        RtpTransportControllerPair());
    EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
    EXPECT_TRUE(
        srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
    EXPECT_TRUE(
        srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2).ok());
    EXPECT_TRUE(
        srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1).ok());
    return srtp_transports;
  }

  SrtpTransportPair CreateSrtpTransportPairAndSetMismatchingKeys(
      const RtpTransportParameters& parameters,
      const UdpTransportPair& rtp_udp_transports) {
    SrtpTransportPair srtp_transports = CreateSrtpTransportPair(
        parameters, rtp_udp_transports, UdpTransportPair(),
        RtpTransportControllerPair());
    EXPECT_TRUE(srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1).ok());
    EXPECT_TRUE(
        srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2).ok());
    EXPECT_TRUE(
        srtp_transports.second->SetSrtpSendKey(kTestCryptoParams1).ok());
    EXPECT_TRUE(
        srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams2).ok());
    return srtp_transports;
  }

  // Ends up using fake audio capture module, which was passed into OrtcFactory
  // on creation.
  rtc::scoped_refptr<webrtc::AudioTrackInterface> CreateLocalAudioTrack(
      const std::string& id,
      OrtcFactoryInterface* ortc_factory) {
    // Disable echo cancellation to make test more efficient.
    cricket::AudioOptions options;
    options.echo_cancellation.emplace(true);
    rtc::scoped_refptr<webrtc::AudioSourceInterface> source =
        ortc_factory->CreateAudioSource(options);
    return ortc_factory->CreateAudioTrack(id, source);
  }

  // Stores created video source in |fake_video_track_sources_|.
  rtc::scoped_refptr<webrtc::VideoTrackInterface>
  CreateLocalVideoTrackAndFakeSource(const std::string& id,
                                     OrtcFactoryInterface* ortc_factory) {
    fake_video_track_sources_.emplace_back(
        new rtc::RefCountedObject<FakePeriodicVideoTrackSource>(
            false /* remote */));
    return rtc::scoped_refptr<VideoTrackInterface>(
        ortc_factory->CreateVideoTrack(id, fake_video_track_sources_.back()));
  }

  // Helper function used to test two way RTP senders and receivers with basic
  // configurations.
  // If |expect_success| is true, waits for kDefaultTimeout for
  // kDefaultNumFrames frames to be received by all RtpReceivers.
  // If |expect_success| is false, simply waits for |kReceivingDuration|, and
  // stores the number of received frames in |received_audio_frame1_| etc.
  void BasicTwoWayRtpSendersAndReceiversTest(RtpTransportPair srtp_transports,
                                             bool expect_success) {
    received_audio_frames1_ = 0;
    received_audio_frames2_ = 0;
    rendered_video_frames1_ = 0;
    rendered_video_frames2_ = 0;
    // Create all the senders and receivers (four per endpoint).
    auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
        cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
    auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
        cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
    auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
        cricket::MEDIA_TYPE_AUDIO, srtp_transports.first.get());
    auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
        cricket::MEDIA_TYPE_VIDEO, srtp_transports.first.get());
    ASSERT_TRUE(audio_sender_result1.ok());
    ASSERT_TRUE(video_sender_result1.ok());
    ASSERT_TRUE(audio_receiver_result1.ok());
    ASSERT_TRUE(video_receiver_result1.ok());
    auto audio_sender1 = audio_sender_result1.MoveValue();
    auto video_sender1 = video_sender_result1.MoveValue();
    auto audio_receiver1 = audio_receiver_result1.MoveValue();
    auto video_receiver1 = video_receiver_result1.MoveValue();

    auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
        cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
    auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
        cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
    auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
        cricket::MEDIA_TYPE_AUDIO, srtp_transports.second.get());
    auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
        cricket::MEDIA_TYPE_VIDEO, srtp_transports.second.get());
    ASSERT_TRUE(audio_sender_result2.ok());
    ASSERT_TRUE(video_sender_result2.ok());
    ASSERT_TRUE(audio_receiver_result2.ok());
    ASSERT_TRUE(video_receiver_result2.ok());
    auto audio_sender2 = audio_sender_result2.MoveValue();
    auto video_sender2 = video_sender_result2.MoveValue();
    auto audio_receiver2 = audio_receiver_result2.MoveValue();
    auto video_receiver2 = video_receiver_result2.MoveValue();

    // Add fake tracks.
    RTCError error = audio_sender1->SetTrack(
        CreateLocalAudioTrack("audio", ortc_factory1_.get()));
    EXPECT_TRUE(error.ok());
    error = video_sender1->SetTrack(
        CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
    EXPECT_TRUE(error.ok());
    error = audio_sender2->SetTrack(
        CreateLocalAudioTrack("audio", ortc_factory2_.get()));
    EXPECT_TRUE(error.ok());
    error = video_sender2->SetTrack(
        CreateLocalVideoTrackAndFakeSource("video", ortc_factory2_.get()));
    EXPECT_TRUE(error.ok());

    // "sent_X_parameters1" are the parameters that endpoint 1 sends with and
    // endpoint 2 receives with.
    RtpParameters sent_opus_parameters1 =
        MakeMinimalOpusParametersWithSsrc(0xdeadbeef);
    RtpParameters sent_vp8_parameters1 =
        MakeMinimalVp8ParametersWithSsrc(0xbaadfeed);
    RtpParameters sent_opus_parameters2 =
        MakeMinimalOpusParametersWithSsrc(0x13333337);
    RtpParameters sent_vp8_parameters2 =
        MakeMinimalVp8ParametersWithSsrc(0x12345678);

    // Configure the senders' and receivers' parameters.
    EXPECT_TRUE(audio_receiver1->Receive(sent_opus_parameters2).ok());
    EXPECT_TRUE(video_receiver1->Receive(sent_vp8_parameters2).ok());
    EXPECT_TRUE(audio_receiver2->Receive(sent_opus_parameters1).ok());
    EXPECT_TRUE(video_receiver2->Receive(sent_vp8_parameters1).ok());
    EXPECT_TRUE(audio_sender1->Send(sent_opus_parameters1).ok());
    EXPECT_TRUE(video_sender1->Send(sent_vp8_parameters1).ok());
    EXPECT_TRUE(audio_sender2->Send(sent_opus_parameters2).ok());
    EXPECT_TRUE(video_sender2->Send(sent_vp8_parameters2).ok());

    FakeVideoTrackRenderer fake_video_renderer1(
        static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
    FakeVideoTrackRenderer fake_video_renderer2(
        static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));

    if (expect_success) {
      EXPECT_TRUE_WAIT(
          fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
              fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
              fake_audio_capture_module2_->frames_received() >
                  kDefaultNumFrames &&
              fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
          kDefaultTimeout)
          << "Audio capture module 1 received "
          << fake_audio_capture_module1_->frames_received()
          << " frames, Video renderer 1 rendered "
          << fake_video_renderer1.num_rendered_frames()
          << " frames, Audio capture module 2 received "
          << fake_audio_capture_module2_->frames_received()
          << " frames, Video renderer 2 rendered "
          << fake_video_renderer2.num_rendered_frames() << " frames.";
    } else {
      WAIT(false, kReceivingDuration);
      rendered_video_frames1_ = fake_video_renderer1.num_rendered_frames();
      rendered_video_frames2_ = fake_video_renderer2.num_rendered_frames();
      received_audio_frames1_ = fake_audio_capture_module1_->frames_received();
      received_audio_frames2_ = fake_audio_capture_module2_->frames_received();
    }
  }

  rtc::VirtualSocketServer virtual_socket_server_;
  rtc::Thread network_thread_;
  rtc::FakeNetworkManager fake_network_manager_;
  rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module1_;
  rtc::scoped_refptr<FakeAudioCaptureModule> fake_audio_capture_module2_;
  std::unique_ptr<OrtcFactoryInterface> ortc_factory1_;
  std::unique_ptr<OrtcFactoryInterface> ortc_factory2_;
  std::vector<rtc::scoped_refptr<VideoTrackSource>> fake_video_track_sources_;
  int received_audio_frames1_ = 0;
  int received_audio_frames2_ = 0;
  int rendered_video_frames1_ = 0;
  int rendered_video_frames2_ = 0;
};

// Disable for TSan v2, see
// https://bugs.chromium.org/p/webrtc/issues/detail?id=7366 for details.
#if !defined(THREAD_SANITIZER)

// Very basic end-to-end test with a single pair of audio RTP sender and
// receiver.
//
// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
// known to work.
TEST_F(OrtcFactoryIntegrationTest, BasicOneWayAudioRtpSenderAndReceiver) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto rtp_transports =
      CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);

  auto sender_result = ortc_factory1_->CreateRtpSender(
      cricket::MEDIA_TYPE_AUDIO, rtp_transports.first.get());
  auto receiver_result = ortc_factory2_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_AUDIO, rtp_transports.second.get());
  ASSERT_TRUE(sender_result.ok());
  ASSERT_TRUE(receiver_result.ok());
  auto sender = sender_result.MoveValue();
  auto receiver = receiver_result.MoveValue();

  RTCError error =
      sender->SetTrack(CreateLocalAudioTrack("audio", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());

  RtpParameters opus_parameters = MakeMinimalOpusParameters();
  EXPECT_TRUE(receiver->Receive(opus_parameters).ok());
  EXPECT_TRUE(sender->Send(opus_parameters).ok());
  // Sender and receiver are connected and configured; audio frames should be
  // able to flow at this point.
  EXPECT_TRUE_WAIT(
      fake_audio_capture_module2_->frames_received() > kDefaultNumFrames,
      kDefaultTimeout);
}

// Very basic end-to-end test with a single pair of video RTP sender and
// receiver.
//
// Uses muxed RTCP, and minimal parameters with a hard-coded config that's
// known to work.
TEST_F(OrtcFactoryIntegrationTest, BasicOneWayVideoRtpSenderAndReceiver) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto rtp_transports =
      CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);

  auto sender_result = ortc_factory1_->CreateRtpSender(
      cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
  auto receiver_result = ortc_factory2_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
  ASSERT_TRUE(sender_result.ok());
  ASSERT_TRUE(receiver_result.ok());
  auto sender = sender_result.MoveValue();
  auto receiver = receiver_result.MoveValue();

  RTCError error = sender->SetTrack(
      CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());

  RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
  EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
  EXPECT_TRUE(sender->Send(vp8_parameters).ok());
  FakeVideoTrackRenderer fake_renderer(
      static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
  // Sender and receiver are connected and configured; video frames should be
  // able to flow at this point.
  EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
                   kDefaultTimeout);
}

// Test that if the track is changed while sending, the sender seamlessly
// transitions to sending it and frames are received end-to-end.
//
// Only doing this for video, since given that audio is sourced from a single
// fake audio capture module, the audio track is just a dummy object.
// TODO(deadbeef): Change this when possible.
TEST_F(OrtcFactoryIntegrationTest, SetTrackWhileSending) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto rtp_transports =
      CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);

  auto sender_result = ortc_factory1_->CreateRtpSender(
      cricket::MEDIA_TYPE_VIDEO, rtp_transports.first.get());
  auto receiver_result = ortc_factory2_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_VIDEO, rtp_transports.second.get());
  ASSERT_TRUE(sender_result.ok());
  ASSERT_TRUE(receiver_result.ok());
  auto sender = sender_result.MoveValue();
  auto receiver = receiver_result.MoveValue();

  RTCError error = sender->SetTrack(
      CreateLocalVideoTrackAndFakeSource("video_1", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());
  RtpParameters vp8_parameters = MakeMinimalVp8Parameters();
  EXPECT_TRUE(receiver->Receive(vp8_parameters).ok());
  EXPECT_TRUE(sender->Send(vp8_parameters).ok());
  FakeVideoTrackRenderer fake_renderer(
      static_cast<VideoTrackInterface*>(receiver->GetTrack().get()));
  // Expect for some initial number of frames to be received.
  EXPECT_TRUE_WAIT(fake_renderer.num_rendered_frames() > kDefaultNumFrames,
                   kDefaultTimeout);
  // Destroy old source, set a new track, and verify new frames are received
  // from the new track. The VideoTrackSource is reference counted and may live
  // a little longer, so tell it that its source is going away now.
  fake_video_track_sources_[0] = nullptr;
  int prev_num_frames = fake_renderer.num_rendered_frames();
  error = sender->SetTrack(
      CreateLocalVideoTrackAndFakeSource("video_2", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());
  EXPECT_TRUE_WAIT(
      fake_renderer.num_rendered_frames() > kDefaultNumFrames + prev_num_frames,
      kDefaultTimeout);
}

// TODO(webrtc:7915, webrtc:9184): Tests below are disabled for iOS 64 on debug
// builds because of flakiness.
#if !(defined(WEBRTC_IOS) && defined(WEBRTC_ARCH_64_BITS) && !defined(NDEBUG))
#define MAYBE_BasicTwoWayAudioVideoRtpSendersAndReceivers \
  BasicTwoWayAudioVideoRtpSendersAndReceivers
#define MAYBE_BasicTwoWayAudioVideoSrtpSendersAndReceivers \
  BasicTwoWayAudioVideoSrtpSendersAndReceivers
#define MAYBE_SrtpSendersAndReceiversWithMismatchingKeys \
  SrtpSendersAndReceiversWithMismatchingKeys
#define MAYBE_OneSideSrtpSenderAndReceiver OneSideSrtpSenderAndReceiver
#define MAYBE_FullTwoWayAudioVideoSrtpSendersAndReceivers \
  FullTwoWayAudioVideoSrtpSendersAndReceivers
#else
#define MAYBE_BasicTwoWayAudioVideoRtpSendersAndReceivers \
  DISABLED_BasicTwoWayAudioVideoRtpSendersAndReceivers
#define MAYBE_BasicTwoWayAudioVideoSrtpSendersAndReceivers \
  DISABLED_BasicTwoWayAudioVideoSrtpSendersAndReceivers
#define MAYBE_SrtpSendersAndReceiversWithMismatchingKeys \
  DISABLED_SrtpSendersAndReceiversWithMismatchingKeys
#define MAYBE_OneSideSrtpSenderAndReceiver DISABLED_OneSideSrtpSenderAndReceiver
#define MAYBE_FullTwoWayAudioVideoSrtpSendersAndReceivers \
  DISABLED_FullTwoWayAudioVideoSrtpSendersAndReceivers
#endif

// End-to-end test with two pairs of RTP senders and receivers, for audio and
// video.
//
// Uses muxed RTCP, and minimal parameters with hard-coded configs that are
// known to work.
TEST_F(OrtcFactoryIntegrationTest,
       MAYBE_BasicTwoWayAudioVideoRtpSendersAndReceivers) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto rtp_transports =
      CreateRtpTransportPair(MakeRtcpMuxParameters(), udp_transports);
  bool expect_success = true;
  BasicTwoWayRtpSendersAndReceiversTest(std::move(rtp_transports),
                                        expect_success);
}

TEST_F(OrtcFactoryIntegrationTest,
       MAYBE_BasicTwoWayAudioVideoSrtpSendersAndReceivers) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto srtp_transports = CreateSrtpTransportPairAndSetKeys(
      MakeRtcpMuxParameters(), udp_transports);
  bool expect_success = true;
  BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
                                        expect_success);
}

// Tests that the packets cannot be decoded if the keys are mismatched.
// TODO(webrtc:9184): Disabled because this test is flaky.
TEST_F(OrtcFactoryIntegrationTest,
       MAYBE_SrtpSendersAndReceiversWithMismatchingKeys) {
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto srtp_transports = CreateSrtpTransportPairAndSetMismatchingKeys(
      MakeRtcpMuxParameters(), udp_transports);
  bool expect_success = false;
  BasicTwoWayRtpSendersAndReceiversTest(std::move(srtp_transports),
                                        expect_success);
  // No frames are expected to be decoded.
  EXPECT_TRUE(received_audio_frames1_ == 0 && received_audio_frames2_ == 0 &&
              rendered_video_frames1_ == 0 && rendered_video_frames2_ == 0);
}

// Tests that the frames cannot be decoded if only one side uses SRTP.
TEST_F(OrtcFactoryIntegrationTest, MAYBE_OneSideSrtpSenderAndReceiver) {
  auto rtcp_parameters = MakeRtcpMuxParameters();
  auto udp_transports = CreateAndConnectUdpTransportPair();
  auto rtcp_udp_transports = UdpTransportPair();
  auto transport_controllers = RtpTransportControllerPair();
  auto transport_result1 = ortc_factory1_->CreateRtpTransport(
      rtcp_parameters, udp_transports.first.get(),
      rtcp_udp_transports.first.get(), transport_controllers.first.get());
  auto transport_result2 = ortc_factory2_->CreateSrtpTransport(
      rtcp_parameters, udp_transports.second.get(),
      rtcp_udp_transports.second.get(), transport_controllers.second.get());

  auto rtp_transport = transport_result1.MoveValue();
  auto srtp_transport = transport_result2.MoveValue();
  EXPECT_TRUE(srtp_transport->SetSrtpSendKey(kTestCryptoParams1).ok());
  EXPECT_TRUE(srtp_transport->SetSrtpReceiveKey(kTestCryptoParams2).ok());
  bool expect_success = false;
  BasicTwoWayRtpSendersAndReceiversTest(
      {std::move(rtp_transport), std::move(srtp_transport)}, expect_success);

  // The SRTP side is not expected to decode any audio or video frames.
  // The RTP side is not expected to decode any video frames while it is
  // possible that the encrypted audio frames can be accidentally decoded which
  // is why received_audio_frames1_ is not validated.
  EXPECT_TRUE(received_audio_frames2_ == 0 && rendered_video_frames1_ == 0 &&
              rendered_video_frames2_ == 0);
}

// End-to-end test with two pairs of RTP senders and receivers, for audio and
// video. Unlike the test above, this attempts to make the parameters as
// complex as possible. The senders and receivers use the SRTP transport with
// different keys.
//
// Uses non-muxed RTCP, with separate audio/video transports, and a full set of
// parameters, as would normally be used in a PeerConnection.
//
// TODO(deadbeef): Update this test as more audio/video features become
// supported.
TEST_F(OrtcFactoryIntegrationTest,
       MAYBE_FullTwoWayAudioVideoSrtpSendersAndReceivers) {
  // We want four pairs of UDP transports for this test, for audio/video and
  // RTP/RTCP.
  auto audio_rtp_udp_transports = CreateAndConnectUdpTransportPair();
  auto audio_rtcp_udp_transports = CreateAndConnectUdpTransportPair();
  auto video_rtp_udp_transports = CreateAndConnectUdpTransportPair();
  auto video_rtcp_udp_transports = CreateAndConnectUdpTransportPair();

  // Since we have multiple RTP transports on each side, we need an RTP
  // transport controller.
  auto transport_controllers = CreateRtpTransportControllerPair();

  RtpTransportParameters audio_rtp_transport_parameters;
  audio_rtp_transport_parameters.rtcp.mux = false;
  auto audio_srtp_transports = CreateSrtpTransportPair(
      audio_rtp_transport_parameters, audio_rtp_udp_transports,
      audio_rtcp_udp_transports, transport_controllers);

  RtpTransportParameters video_rtp_transport_parameters;
  video_rtp_transport_parameters.rtcp.mux = false;
  video_rtp_transport_parameters.rtcp.reduced_size = true;
  auto video_srtp_transports = CreateSrtpTransportPair(
      video_rtp_transport_parameters, video_rtp_udp_transports,
      video_rtcp_udp_transports, transport_controllers);

  // Set keys for SRTP transports.
  audio_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams1);
  audio_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams2);
  video_srtp_transports.first->SetSrtpSendKey(kTestCryptoParams3);
  video_srtp_transports.first->SetSrtpReceiveKey(kTestCryptoParams4);

  audio_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams2);
  audio_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams1);
  video_srtp_transports.second->SetSrtpSendKey(kTestCryptoParams4);
  video_srtp_transports.second->SetSrtpReceiveKey(kTestCryptoParams3);

  // Create all the senders and receivers (four per endpoint).
  auto audio_sender_result1 = ortc_factory1_->CreateRtpSender(
      cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
  auto video_sender_result1 = ortc_factory1_->CreateRtpSender(
      cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
  auto audio_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.first.get());
  auto video_receiver_result1 = ortc_factory1_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.first.get());
  ASSERT_TRUE(audio_sender_result1.ok());
  ASSERT_TRUE(video_sender_result1.ok());
  ASSERT_TRUE(audio_receiver_result1.ok());
  ASSERT_TRUE(video_receiver_result1.ok());
  auto audio_sender1 = audio_sender_result1.MoveValue();
  auto video_sender1 = video_sender_result1.MoveValue();
  auto audio_receiver1 = audio_receiver_result1.MoveValue();
  auto video_receiver1 = video_receiver_result1.MoveValue();

  auto audio_sender_result2 = ortc_factory2_->CreateRtpSender(
      cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
  auto video_sender_result2 = ortc_factory2_->CreateRtpSender(
      cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
  auto audio_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_AUDIO, audio_srtp_transports.second.get());
  auto video_receiver_result2 = ortc_factory2_->CreateRtpReceiver(
      cricket::MEDIA_TYPE_VIDEO, video_srtp_transports.second.get());
  ASSERT_TRUE(audio_sender_result2.ok());
  ASSERT_TRUE(video_sender_result2.ok());
  ASSERT_TRUE(audio_receiver_result2.ok());
  ASSERT_TRUE(video_receiver_result2.ok());
  auto audio_sender2 = audio_sender_result2.MoveValue();
  auto video_sender2 = video_sender_result2.MoveValue();
  auto audio_receiver2 = audio_receiver_result2.MoveValue();
  auto video_receiver2 = video_receiver_result2.MoveValue();

  RTCError error = audio_sender1->SetTrack(
      CreateLocalAudioTrack("audio", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());
  error = video_sender1->SetTrack(
      CreateLocalVideoTrackAndFakeSource("video", ortc_factory1_.get()));
  EXPECT_TRUE(error.ok());
  error = audio_sender2->SetTrack(
      CreateLocalAudioTrack("audio", ortc_factory2_.get()));
  EXPECT_TRUE(error.ok());
  error = video_sender2->SetTrack(
      CreateLocalVideoTrackAndFakeSource("video", ortc_factory2_.get()));
  EXPECT_TRUE(error.ok());

  // Use different codecs in different directions for extra challenge.
  RtpParameters opus_send_parameters = MakeFullOpusParameters();
  RtpParameters isac_send_parameters = MakeFullIsacParameters();
  RtpParameters vp8_send_parameters = MakeFullVp8Parameters();
  RtpParameters vp9_send_parameters = MakeFullVp9Parameters();

  // Remove "payload_type" from receive parameters. Receiver will need to
  // discern the payload type from packets received.
  RtpParameters opus_receive_parameters = opus_send_parameters;
  RtpParameters isac_receive_parameters = isac_send_parameters;
  RtpParameters vp8_receive_parameters = vp8_send_parameters;
  RtpParameters vp9_receive_parameters = vp9_send_parameters;
  opus_receive_parameters.encodings[0].codec_payload_type.reset();
  isac_receive_parameters.encodings[0].codec_payload_type.reset();
  vp8_receive_parameters.encodings[0].codec_payload_type.reset();
  vp9_receive_parameters.encodings[0].codec_payload_type.reset();

  // Configure the senders' and receivers' parameters.
  //
  // Note: Intentionally, the top codec in the receive parameters does not
  // match the codec sent by the other side. If "Receive" is called with a list
  // of codecs, the receiver should be prepared to receive any of them, not
  // just the one on top.
  EXPECT_TRUE(audio_receiver1->Receive(opus_receive_parameters).ok());
  EXPECT_TRUE(video_receiver1->Receive(vp8_receive_parameters).ok());
  EXPECT_TRUE(audio_receiver2->Receive(isac_receive_parameters).ok());
  EXPECT_TRUE(video_receiver2->Receive(vp9_receive_parameters).ok());
  EXPECT_TRUE(audio_sender1->Send(opus_send_parameters).ok());
  EXPECT_TRUE(video_sender1->Send(vp8_send_parameters).ok());
  EXPECT_TRUE(audio_sender2->Send(isac_send_parameters).ok());
  EXPECT_TRUE(video_sender2->Send(vp9_send_parameters).ok());

  FakeVideoTrackRenderer fake_video_renderer1(
      static_cast<VideoTrackInterface*>(video_receiver1->GetTrack().get()));
  FakeVideoTrackRenderer fake_video_renderer2(
      static_cast<VideoTrackInterface*>(video_receiver2->GetTrack().get()));

  // Senders and receivers are connected and configured; audio and video frames
  // should be able to flow at this point.
  EXPECT_TRUE_WAIT(
      fake_audio_capture_module1_->frames_received() > kDefaultNumFrames &&
          fake_video_renderer1.num_rendered_frames() > kDefaultNumFrames &&
          fake_audio_capture_module2_->frames_received() > kDefaultNumFrames &&
          fake_video_renderer2.num_rendered_frames() > kDefaultNumFrames,
      kDefaultTimeout);
}

// TODO(deadbeef): End-to-end test for multiple senders/receivers of the same
// media type, once that's supported. Currently, it is not because the
// BaseChannel model relies on there being a single VoiceChannel and
// VideoChannel, and these only support a single set of codecs/etc. per
// send/receive direction.

// TODO(deadbeef): End-to-end test for simulcast, once that's supported by this
// API.

#endif  // if !defined(THREAD_SANITIZER)

}  // namespace webrtc
