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