/*
 *  Copyright 2004 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 "pc/codec_vendor.h"

#include <string>
#include <utility>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/environment/environment.h"
#include "api/field_trials.h"
#include "api/media_types.h"
#include "api/payload_type.h"
#include "api/rtc_error.h"
#include "api/rtp_transceiver_direction.h"
#include "api/test/rtc_error_matchers.h"
#include "call/fake_payload_type_suggester.h"
#include "media/base/codec.h"
#include "media/base/codec_list.h"
#include "media/base/fake_media_engine.h"
#include "media/base/media_constants.h"
#include "media/base/test_utils.h"
#include "pc/media_options.h"
#include "pc/rtp_parameters_conversion.h"
#include "pc/session_description.h"
#include "rtc_base/checks.h"
#include "test/create_test_environment.h"
#include "test/create_test_field_trials.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::Contains;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Ne;
using ::testing::Not;
using ::testing::Pair;

Codec CreateRedAudioCodec(absl::string_view encoding_id) {
  Codec red = CreateAudioCodec(63, "red", 48000, 2);
  red.SetParam(kCodecParamNotInNameValueFormat,
               std::string(encoding_id) + '/' + std::string(encoding_id));
  return red;
}

const Codec kAudioCodecs1[] = {CreateAudioCodec(111, "opus", 48000, 2),
                               CreateRedAudioCodec("111"),
                               CreateAudioCodec(102, "G722", 16000, 1),
                               CreateAudioCodec(0, "PCMU", 8000, 1),
                               CreateAudioCodec(8, "PCMA", 8000, 1),
                               CreateAudioCodec(107, "CN", 48000, 1)};

const Codec kAudioCodecs2[] = {
    CreateAudioCodec(126, "foo", 16000, 1),
    CreateAudioCodec(0, "PCMU", 8000, 1),
    CreateAudioCodec(127, "G722", 16000, 1),
};

const Codec kAudioCodecsAnswer[] = {
    CreateAudioCodec(102, "G722", 16000, 1),
    CreateAudioCodec(0, "PCMU", 8000, 1),
};

TEST(CodecVendorTest, TestSetAudioCodecs) {
  FieldTrials trials =
      CreateTestFieldTrials("WebRTC-PayloadTypesInTransport/Disabled/");
  std::vector<Codec> send_codecs = MAKE_VECTOR(kAudioCodecs1);
  std::vector<Codec> recv_codecs = MAKE_VECTOR(kAudioCodecs2);

  // The merged list of codecs should contain any send codecs that are also
  // nominally in the receive codecs list. Payload types should be picked from
  // the send codecs and a number-of-channels of 0 and 1 should be equivalent
  // (set to 1). This equals what happens when the send codecs are used in an
  // offer and the receive codecs are used in the following answer.
  const std::vector<Codec> sendrecv_codecs = MAKE_VECTOR(kAudioCodecsAnswer);
  RTC_CHECK_EQ(send_codecs[2].name, "G722")
      << "Please don't change shared test data!";
  RTC_CHECK_EQ(recv_codecs[2].name, "G722")
      << "Please don't change shared test data!";
  // Alter iLBC send codec to have zero channels, to test that that is handled
  // properly.
  send_codecs[2].channels = 0;

  // Alter PCMU receive codec to be lowercase, to test that case conversions
  // are handled properly.
  recv_codecs[1].name = "pcmu";

  // Test proper merge
  FakeMediaEngine media_engine;
  media_engine.SetAudioSendCodecs(send_codecs);
  media_engine.SetAudioRecvCodecs(recv_codecs);
  {
    CodecVendor codec_vendor(&media_engine, false, trials);
    EXPECT_EQ(send_codecs, codec_vendor.audio_send_codecs().codecs());
    EXPECT_EQ(recv_codecs, codec_vendor.audio_recv_codecs().codecs());
    EXPECT_EQ(sendrecv_codecs, codec_vendor.audio_sendrecv_codecs().codecs());
  }

  // Test empty send codecs list
  CodecList no_codecs;
  media_engine.SetAudioSendCodecs(no_codecs.codecs());
  media_engine.SetAudioRecvCodecs(recv_codecs);
  {
    CodecVendor codec_vendor(&media_engine, false, trials);
    EXPECT_EQ(no_codecs.codecs(), codec_vendor.audio_send_codecs().codecs());
    EXPECT_EQ(recv_codecs, codec_vendor.audio_recv_codecs().codecs());
    EXPECT_EQ(no_codecs.codecs(),
              codec_vendor.audio_sendrecv_codecs().codecs());
  }

  // Test empty recv codecs list
  media_engine.SetAudioSendCodecs(send_codecs);
  media_engine.SetAudioRecvCodecs(no_codecs.codecs());
  {
    CodecVendor codec_vendor(&media_engine, false, trials);
    EXPECT_EQ(send_codecs, codec_vendor.audio_send_codecs().codecs());
    EXPECT_EQ(no_codecs.codecs(), codec_vendor.audio_recv_codecs().codecs());
    EXPECT_EQ(no_codecs.codecs(),
              codec_vendor.audio_sendrecv_codecs().codecs());
  }

  // Test all empty codec lists
  media_engine.SetAudioSendCodecs(no_codecs.codecs());
  media_engine.SetAudioRecvCodecs(no_codecs.codecs());
  {
    CodecVendor codec_vendor(&media_engine, false, trials);
    EXPECT_EQ(no_codecs.codecs(), codec_vendor.audio_send_codecs().codecs());
    EXPECT_EQ(no_codecs.codecs(), codec_vendor.audio_recv_codecs().codecs());
    EXPECT_EQ(no_codecs.codecs(),
              codec_vendor.audio_sendrecv_codecs().codecs());
  }
}

TEST(CodecVendorTest, VideoRtxIsIncludedWhenAskedFor) {
  Environment env = CreateTestEnvironment(
      {.field_trials = "WebRTC-PayloadTypesInTransport/Disabled/"});
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoRtxCodec(98, 97),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  CodecVendor codec_vendor(&media_engine, /* rtx_enabled= */ true,
                           env.field_trials());
  FakePayloadTypeSuggester pt_suggester;
  RTCErrorOr<std::vector<Codec>> offered_codecs =
      codec_vendor.GetNegotiatedCodecsForOffer(
          MediaDescriptionOptions(MediaType::VIDEO, "mid",
                                  RtpTransceiverDirection::kSendOnly, false),
          MediaSessionOptions(), nullptr, pt_suggester);
  EXPECT_THAT(offered_codecs.value(),
              Contains(Field("name", &Codec::name, "rtx")));
}

TEST(CodecVendorTest, VideoRtxIsExcludedWhenNotAskedFor) {
  Environment env = CreateTestEnvironment(
      {.field_trials = "WebRTC-PayloadTypesInTransport/Disabled/"});
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoRtxCodec(98, 97),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  CodecVendor codec_vendor(&media_engine, /* rtx_enabled= */ false,
                           env.field_trials());
  FakePayloadTypeSuggester pt_suggester;
  RTCErrorOr<std::vector<Codec>> offered_codecs =
      codec_vendor.GetNegotiatedCodecsForOffer(
          MediaDescriptionOptions(MediaType::VIDEO, "mid",
                                  RtpTransceiverDirection::kSendOnly, false),
          MediaSessionOptions(), nullptr, pt_suggester);
  EXPECT_THAT(offered_codecs.value(),
              Not(Contains(Field("name", &Codec::name, "rtx"))));
}

TEST(CodecVendorTest, PreferencesAffectCodecChoice) {
  Environment env = CreateTestEnvironment(
      {.field_trials = "WebRTC-PayloadTypesInTransport/Disabled/"});
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoRtxCodec(98, 97),
      CreateVideoCodec(99, "vp9"),
      CreateVideoRtxCodec(100, 99),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  CodecVendor codec_vendor(&media_engine, /* rtx_enabled= */ false,
                           env.field_trials());
  MediaDescriptionOptions options(MediaType::VIDEO, "mid",
                                  RtpTransceiverDirection::kSendOnly, false);
  options.codec_preferences = {
      ToRtpCodecCapability(CreateVideoCodec(PayloadType::NotSet(), "vp9")),
  };
  FakePayloadTypeSuggester pt_suggester;

  RTCErrorOr<std::vector<Codec>> offered_codecs =
      codec_vendor.GetNegotiatedCodecsForOffer(options, MediaSessionOptions(),
                                               nullptr, pt_suggester);
  ASSERT_TRUE(offered_codecs.ok());
  EXPECT_THAT(offered_codecs.value(),
              Contains(Field("name", &Codec::name, "vp9")));
  EXPECT_THAT(offered_codecs.value(),
              Not(Contains(Field("name", &Codec::name, "vp8"))));
  EXPECT_THAT(offered_codecs.value().size(), Eq(1));
}

TEST(CodecVendorTest, GetNegotiatedCodecsForAnswerSimple) {
  Environment env = CreateTestEnvironment(
      {.field_trials = "WebRTC-PayloadTypesInTransport/Disabled/"});
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoRtxCodec(98, 97),
      CreateVideoCodec(99, "vp9"),
      CreateVideoRtxCodec(100, 99),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  CodecVendor codec_vendor(&media_engine, /* rtx_enabled= */ true,
                           env.field_trials());
  MediaDescriptionOptions options(MediaType::VIDEO, "mid",
                                  RtpTransceiverDirection::kSendOnly, false);
  FakePayloadTypeSuggester pt_suggester;
  ContentInfo* current_content = nullptr;
  RTCErrorOr<std::vector<Codec>> answered_codecs =
      codec_vendor.GetNegotiatedCodecsForAnswer(
          options, MediaSessionOptions(), RtpTransceiverDirection::kSendOnly,
          RtpTransceiverDirection::kSendOnly, current_content, video_codecs,
          pt_suggester);
  EXPECT_THAT(answered_codecs, IsRtcOkAndHolds(video_codecs));
}

TEST(CodecVendorTest, GetNegotiatedCodecsForAnswerWithCollision) {
  Environment env = CreateTestEnvironment(
      {.field_trials = "WebRTC-PayloadTypesInTransport/Disabled/"});
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoCodec(99, "vp9"),
      CreateVideoCodec(101, "av1"),
  });
  std::vector<Codec> remote_codecs({
      CreateVideoCodec(97, "av1"),
      CreateVideoCodec(99, "vp9"),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  CodecVendor codec_vendor(&media_engine, /* rtx_enabled= */ false,
                           env.field_trials());
  MediaDescriptionOptions options(MediaType::VIDEO, "mid",
                                  RtpTransceiverDirection::kSendOnly, false);
  FakePayloadTypeSuggester pt_suggester;
  ContentInfo* current_content = nullptr;
  RTCErrorOr<std::vector<Codec>> answered_codecs =
      codec_vendor.GetNegotiatedCodecsForAnswer(
          options, MediaSessionOptions(), RtpTransceiverDirection::kSendOnly,
          RtpTransceiverDirection::kSendOnly, current_content, remote_codecs,
          pt_suggester);
  EXPECT_THAT(answered_codecs, IsRtcOkAndHolds(remote_codecs));
}

TEST(CodecVendorMergeTest, BasicTestSetup) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_TRUE(error.ok());
}

TEST(CodecVendorMergeTest, IdenticalListsMergeWithNoChange) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  Codec some_codec = CreateVideoCodec(97, "foo");
  RTCErrorOr<PayloadType> pt_or_error =
      pt_suggester.SuggestPayloadType(mid, some_codec, false);
  ASSERT_THAT(pt_or_error.value(), Eq(97));
  reference_codecs.push_back(some_codec);
  merged_codecs.push_back(some_codec);
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_TRUE(error.ok());
  EXPECT_THAT(merged_codecs.size(), Eq(1));
  EXPECT_THAT(merged_codecs[0].id, Eq(97));
}

TEST(CodecVendorMergeTest, MergeRenumbersAdditionalCodecs) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  Codec some_codec = CreateVideoCodec(97, "foo");
  RTCErrorOr<PayloadType> pt_or_error =
      pt_suggester.SuggestPayloadType(mid, some_codec, false);
  ASSERT_THAT(pt_or_error.value(), Eq(97));
  merged_codecs.push_back(some_codec);
  // Use the same PT for a reference codec. This should be renumbered.
  Codec some_other_codec = CreateVideoCodec(97, "bar");
  reference_codecs.push_back(some_other_codec);
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_TRUE(error.ok());
  EXPECT_THAT(merged_codecs.size(), Eq(2));
  // Both foo and bar should be present
  EXPECT_THAT(merged_codecs.codecs(),
              UnorderedElementsAre(Field("name", &Codec::name, "foo"),
                                   Field("name", &Codec::name, "bar")));
  // Foo should retain 97
  EXPECT_THAT(merged_codecs.codecs(),
              Contains(AllOf(Field("name", &Codec::name, "foo"),
                             Field("id", &Codec::id, 97))));
  // Bar should not have 97
  EXPECT_THAT(merged_codecs.codecs(),
              Contains(AllOf(Field("name", &Codec::name, "bar"),
                             Field("id", &Codec::id, Ne(97)))));
}

TEST(CodecVendorMergeTest, MergeRenumbersRedCodecArgument) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  Codec some_codec = CreateAudioCodec(100, "foo", 8000, 1);
  merged_codecs.push_back(some_codec);
  // Push into "reference" with a different ID
  some_codec.id = 102;
  reference_codecs.push_back(some_codec);
  Codec red_codec = CreateAudioCodec(101, "red", 8000, 1);
  ASSERT_EQ(red_codec.GetResiliencyType(), Codec::ResiliencyType::kRed);
  red_codec.SetParam(kCodecParamNotInNameValueFormat, "102/102");
  reference_codecs.push_back(red_codec);
  // Merging should add the RED codec with parameter 100/100
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_TRUE(error.ok());
  EXPECT_THAT(merged_codecs.size(), Eq(2));
  EXPECT_THAT(
      merged_codecs.codecs(),
      Contains(AllOf(Field("name", &Codec::name, "red"),
                     Field("params", &Codec::params,
                           ElementsAre(Pair(kCodecParamNotInNameValueFormat,
                                            "100/100"))))));
}

TEST(CodecVendorMergeTest, MergeRenumbersRedCodecArgumentAndMerges) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  Codec some_codec = CreateAudioCodec(100, "foo", 8000, 1);
  merged_codecs.push_back(some_codec);
  // Push into "reference" with a different ID
  some_codec.id = 102;
  reference_codecs.push_back(some_codec);
  Codec red_codec = CreateAudioCodec(101, "red", 8000, 1);
  ASSERT_EQ(red_codec.GetResiliencyType(), Codec::ResiliencyType::kRed);
  red_codec.SetParam(kCodecParamNotInNameValueFormat, "102/102");
  reference_codecs.push_back(red_codec);
  // Push the same red codec into `merged_codecs` with the 100 id
  red_codec.SetParam(kCodecParamNotInNameValueFormat, "100/100");
  merged_codecs.push_back(red_codec);
  // Merging should note the duplication and not add another codec.
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_TRUE(error.ok());
  EXPECT_THAT(merged_codecs.size(), Eq(2));
  EXPECT_THAT(
      merged_codecs.codecs(),
      Contains(AllOf(Field("name", &Codec::name, "red"),
                     Field("params", &Codec::params,
                           ElementsAre(Pair(kCodecParamNotInNameValueFormat,
                                            "100/100"))))));
}

TEST(CodecVendorMergeTest, MergeWithBrokenReferenceRedErrors) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  Codec some_codec = CreateAudioCodec(100, "foo", 8000, 1);
  Codec red_codec = CreateAudioCodec(101, "red", 8000, 1);
  // Adds a RED codec that refers to codec 102, which does not exist.
  red_codec.SetParam(kCodecParamNotInNameValueFormat, "100/102");
  reference_codecs.push_back(some_codec);
  reference_codecs.push_back(red_codec);
  // The bogus RED codec should result in an error return.
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester);
  EXPECT_FALSE(error.ok());
  EXPECT_THAT(error.type(), Eq(RTCErrorType::INTERNAL_ERROR));
}

TEST(CodecVendorMergeTest, MergeWithCollisionPicksFromTop) {
  if (CreateTestFieldTrials().IsEnabled("WebRTC-PayloadTypesInTransport")) {
    GTEST_SKIP();
  }
  CodecList reference_codecs;
  const std::string mid = "mid";
  CodecList merged_codecs;
  FakePayloadTypeSuggester pt_suggester;
  // Existing codec with PT 97
  Codec some_codec = CreateVideoCodec(97, "foo");
  merged_codecs.push_back(some_codec);
  RTC_CHECK(pt_suggester.AddLocalMapping(mid, 97, some_codec).ok());

  // New codec in reference that also wants PT 97
  Codec some_other_codec = CreateVideoCodec(97, "bar");
  reference_codecs.push_back(some_other_codec);

  // When merging with pick_from_top_of_range = true, it should pick 127
  RTCError error =
      MergeCodecsForTesting(reference_codecs, mid, merged_codecs, pt_suggester,
                            /*pick_from_top_of_range=*/true);
  EXPECT_TRUE(error.ok());
  EXPECT_THAT(merged_codecs.size(), Eq(2));
  EXPECT_THAT(merged_codecs.codecs(),
              Contains(AllOf(Field("name", &Codec::name, "bar"),
                             Field("id", &Codec::id, 127))));
}

TEST(CodecVendorTest, ModifyVideoCodecsReplacesCodec) {
  FieldTrials trials =
      CreateTestFieldTrials("WebRTC-PayloadTypesInTransport/Disabled/");
  FakeMediaEngine media_engine;
  std::vector<Codec> video_codecs({
      CreateVideoCodec(97, "vp8"),
      CreateVideoCodec(99, "vp9"),
  });
  media_engine.SetVideoSendCodecs(video_codecs);
  media_engine.SetVideoRecvCodecs(video_codecs);

  CodecVendor codec_vendor(&media_engine, false, trials);

  Codec original_codec = video_codecs[0];
  Codec modified_codec = original_codec;
  modified_codec.name = "modified_name";

  Codec second_codec = video_codecs[1];

  std::vector<std::pair<Codec, Codec>> changes;
  changes.push_back({original_codec, modified_codec});

  codec_vendor.ModifyVideoCodecs(changes);

  const CodecList& new_send_codecs = codec_vendor.video_send_codecs();
  EXPECT_THAT(new_send_codecs.codecs(), Contains(modified_codec));
  EXPECT_THAT(new_send_codecs.codecs(), Not(Contains(original_codec)));

  // Check that the second codec is NOT changed.
  EXPECT_THAT(new_send_codecs.codecs(), Contains(second_codec));
}

}  // namespace
}  // namespace webrtc
