/*
 *  Copyright 2025 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/sdp_munging_detector.h"

#include <algorithm>
#include <cstddef>
#include <string>
#include <vector>

#include "absl/algorithm/container.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "api/field_trials_view.h"
#include "api/jsep.h"
#include "api/media_types.h"
#include "api/uma_metrics.h"
#include "media/base/codec.h"
#include "media/base/media_constants.h"
#include "media/base/stream_params.h"
#include "p2p/base/p2p_constants.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "pc/session_description.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"

namespace webrtc {

namespace {

SdpMungingType DetermineTransportModification(
    const TransportInfos& last_created_transport_infos,
    const TransportInfos& transport_infos_to_set) {
  if (last_created_transport_infos.size() != transport_infos_to_set.size()) {
    RTC_LOG(LS_ERROR) << "SDP munging: Number of transport-infos does not "
                         "match last created description.";
    // Number of transports should always match number of contents so this
    // should never happen.
    return SdpMungingType::kNumberOfContents;
  }
  for (size_t i = 0; i < last_created_transport_infos.size(); i++) {
    const TransportDescription& last_created =
        last_created_transport_infos[i].description;
    const TransportDescription& to_set = transport_infos_to_set[i].description;
    if (last_created.ice_ufrag != to_set.ice_ufrag) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice-ufrag does not match last created description.";
      return SdpMungingType::kIceUfrag;
    }
    if (last_created.ice_pwd != to_set.ice_pwd) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice-pwd does not match last created description.";
      return SdpMungingType::kIcePwd;
    }
    if (last_created.ice_mode != to_set.ice_mode) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice mode does not match last created description.";
      return SdpMungingType::kIceMode;
    }
    if (last_created.connection_role != to_set.connection_role) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: DTLS role does not match last created description.";
      return SdpMungingType::kDtlsSetup;
    }
    if (last_created.transport_options != to_set.transport_options) {
      RTC_LOG(LS_WARNING) << "SDP munging: ice_options does not match last "
                             "created description.";
      // This handles the surprisingly common case where the default `trickle`
      // is removed together with the entire ice-options attribute.
      if (!last_created.transport_options.empty() &&
          to_set.transport_options.empty()) {
        return SdpMungingType::kIceOptionsRemoved;
      }
      // Munging new features is not allowed.
      if (last_created.HasOption(ICE_OPTION_SPED) !=
          to_set.HasOption(ICE_OPTION_SPED)) {
        return SdpMungingType::kIceOptionsSped;
      }
      if (!last_created.HasOption(ICE_OPTION_RENOMINATION) &&
          to_set.HasOption(ICE_OPTION_RENOMINATION)) {
        return SdpMungingType::kIceOptionsRenomination;
      }
      if (last_created.HasOption(ICE_OPTION_TRICKLE) &&
          !to_set.HasOption(ICE_OPTION_TRICKLE)) {
        return SdpMungingType::kIceOptionsTrickle;
      }
      return SdpMungingType::kIceOptions;
    }
  }
  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineAudioSdpModification(
    const MediaContentDescription* last_created_media_description,
    const MediaContentDescription* media_description_to_set) {
  RTC_DCHECK(last_created_media_description);
  RTC_DCHECK(media_description_to_set);
  // Removing codecs should be done via setCodecPreferences or negotiation, not
  // munging.
  if (last_created_media_description->codecs().size() >
      media_description_to_set->codecs().size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: audio codecs removed.";
    return SdpMungingType::kAudioCodecsRemoved;
  }
  // Adding audio codecs is measured after the more specific multiopus and L16
  // checks.

  // Opus stereo modification required to enabled stereo playout for opus.
  bool created_opus_stereo =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        std::string value;
                        return codec.name == kOpusCodecName &&
                               codec.GetParam(kCodecParamStereo, &value) &&
                               value == kParamValueTrue;
                      }) != last_created_media_description->codecs().end();
  bool set_opus_stereo =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            std::string value;
            return codec.name == kOpusCodecName &&
                   codec.GetParam(kCodecParamStereo, &value) &&
                   value == kParamValueTrue;
          }) != media_description_to_set->codecs().end();
  if (!created_opus_stereo && set_opus_stereo) {
    RTC_LOG(LS_WARNING) << "SDP munging: Opus stereo enabled.";
    return SdpMungingType::kAudioCodecsFmtpOpusStereo;
  }

  // Nonstandard 5.1/7.1 opus variant.
  bool created_multiopus =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        return codec.name == "multiopus";
                      }) != last_created_media_description->codecs().end();
  bool set_multiopus =
      absl::c_find_if(media_description_to_set->codecs(),
                      [](const Codec codec) {
                        return codec.name == "multiopus";
                      }) != media_description_to_set->codecs().end();
  if (!created_multiopus && set_multiopus) {
    RTC_LOG(LS_WARNING) << "SDP munging: multiopus enabled.";
    return SdpMungingType::kAudioCodecsAddedMultiOpus;
  }

  // L16.
  bool created_l16 =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        return codec.name == kL16CodecName;
                      }) != last_created_media_description->codecs().end();
  bool set_l16 = absl::c_find_if(media_description_to_set->codecs(),
                                 [](const Codec codec) {
                                   return codec.name == kL16CodecName;
                                 }) != media_description_to_set->codecs().end();
  if (!created_l16 && set_l16) {
    RTC_LOG(LS_WARNING) << "SDP munging: L16 enabled.";
    return SdpMungingType::kAudioCodecsAddedL16;
  }

  if (last_created_media_description->codecs().size() <
      media_description_to_set->codecs().size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: audio codecs added.";
    return SdpMungingType::kAudioCodecsAdded;
  }

  // Audio NACK is not offered by default.
  bool created_nack =
      absl::c_find_if(
          last_created_media_description->codecs(), [](const Codec codec) {
            return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack));
          }) != last_created_media_description->codecs().end();
  bool set_nack =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamNack));
          }) != media_description_to_set->codecs().end();
  if (!created_nack && set_nack) {
    RTC_LOG(LS_WARNING) << "SDP munging: audio nack enabled.";
    return SdpMungingType::kAudioCodecsRtcpFbAudioNack;
  }

  // RRTR is not offered by default.
  bool created_rrtr =
      absl::c_find_if(
          last_created_media_description->codecs(), [](const Codec codec) {
            return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamRrtr));
          }) != last_created_media_description->codecs().end();
  bool set_rrtr =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            return codec.HasFeedbackParam(FeedbackParam(kRtcpFbParamRrtr));
          }) != media_description_to_set->codecs().end();
  if (!created_rrtr && set_rrtr) {
    RTC_LOG(LS_WARNING) << "SDP munging: audio rrtr enabled.";
    return SdpMungingType::kAudioCodecsRtcpFbRrtr;
  }

  // Opus FEC is on by default. Should not be munged, can be controlled by
  // the other side.
  bool created_opus_fec =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        std::string value;
                        return codec.name == kOpusCodecName &&
                               codec.GetParam(kCodecParamUseInbandFec,
                                              &value) &&
                               value == kParamValueTrue;
                      }) != last_created_media_description->codecs().end();
  bool set_opus_fec =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            std::string value;
            return codec.name == kOpusCodecName &&
                   codec.GetParam(kCodecParamUseInbandFec, &value) &&
                   value == kParamValueTrue;
          }) != media_description_to_set->codecs().end();
  if (created_opus_fec && !set_opus_fec) {
    RTC_LOG(LS_WARNING) << "SDP munging: Opus FEC disabled.";
    return SdpMungingType::kAudioCodecsFmtpOpusFec;
  }
  // Opus DTX is off by default. Should not be munged, can be controlled by
  // the other side.
  bool created_opus_dtx =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        std::string value;
                        return codec.name == kOpusCodecName &&
                               codec.GetParam(kCodecParamUseDtx, &value) &&
                               value == kParamValueTrue;
                      }) != last_created_media_description->codecs().end();
  bool set_opus_dtx =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            std::string value;
            return codec.name == kOpusCodecName &&
                   codec.GetParam(kCodecParamUseDtx, &value) &&
                   value == kParamValueTrue;
          }) != media_description_to_set->codecs().end();
  if (!created_opus_dtx && set_opus_dtx) {
    RTC_LOG(LS_WARNING) << "SDP munging: Opus DTX enabled.";
    return SdpMungingType::kAudioCodecsFmtpOpusDtx;
  }

  // Opus CBR is off by default. Should not be munged, can be controlled by
  // the other side.
  bool created_opus_cbr =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        std::string value;
                        return codec.name == kOpusCodecName &&
                               codec.GetParam(kCodecParamCbr, &value) &&
                               value == kParamValueTrue;
                      }) != last_created_media_description->codecs().end();
  bool set_opus_cbr =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            std::string value;
            return codec.name == kOpusCodecName &&
                   codec.GetParam(kCodecParamCbr, &value) &&
                   value == kParamValueTrue;
          }) != media_description_to_set->codecs().end();
  if (!created_opus_cbr && set_opus_cbr) {
    RTC_LOG(LS_WARNING) << "SDP munging: Opus CBR enabled.";
    return SdpMungingType::kAudioCodecsFmtpOpusCbr;
  }
  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineRtcpModification(
    const MediaContentDescription* last_created_media_description,
    const MediaContentDescription* media_description_to_set) {
  // rtcp-mux.
  if (last_created_media_description->rtcp_mux() !=
      media_description_to_set->rtcp_mux()) {
    RTC_LOG(LS_WARNING) << "SDP munging: rtcp-mux modified.";
    return SdpMungingType::kRtcpMux;
  }

  // rtcp-rsize.
  if (last_created_media_description->rtcp_reduced_size() !=
      media_description_to_set->rtcp_reduced_size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: rtcp-rsize modified.";
    return last_created_media_description->type() == MediaType::AUDIO
               ? SdpMungingType::kAudioCodecsRtcpReducedSize
               : SdpMungingType::kVideoCodecsRtcpReducedSize;
  }

  // rtcp-xr:rcvr-rtt. The legacy a=rtcp-fb:<pt> rrtr signals the same thing
  // but is a codec feedback param and is measured as kAudioCodecsRtcpFbRrtr.
  if (last_created_media_description->receive_non_sender_rtt() !=
      media_description_to_set->receive_non_sender_rtt()) {
    RTC_LOG(LS_ERROR) << "SDP munging: rtcp-xr rcvr-rtt modified.";
    return SdpMungingType::kRtcpXrRcvrRtt;
  }
  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineCodecModification(
    const MediaContentDescription* last_created_media_description,
    const MediaContentDescription* media_description_to_set) {
  MediaType media_type = last_created_media_description->type();
  // Validate codecs. We should have bailed out earlier if codecs were added
  // or removed.
  auto last_created_codecs = last_created_media_description->codecs();
  auto codecs_to_set = media_description_to_set->codecs();
  if (last_created_codecs.size() == codecs_to_set.size()) {
    for (size_t i = 0; i < last_created_codecs.size(); i++) {
      if (last_created_codecs[i] == codecs_to_set[i]) {
        continue;
      }
      // Codec position swapped.
      for (size_t j = i + 1; j < last_created_codecs.size(); j++) {
        if (last_created_codecs[i] == codecs_to_set[j]) {
          return media_type == MediaType::AUDIO
                     ? SdpMungingType::kAudioCodecsReordered
                     : SdpMungingType::kVideoCodecsReordered;
        }
      }
      // Same codec but id changed.
      if (last_created_codecs[i].name == codecs_to_set[i].name &&
          last_created_codecs[i].id != codecs_to_set[i].id) {
        return SdpMungingType::kPayloadTypes;
      }
      if (last_created_codecs[i].params != codecs_to_set[i].params) {
        return media_type == MediaType::AUDIO
                   ? SdpMungingType::kAudioCodecsFmtp
                   : SdpMungingType::kVideoCodecsFmtp;
      }
      if (last_created_codecs[i].feedback_params !=
          codecs_to_set[i].feedback_params) {
        return media_type == MediaType::AUDIO
                   ? SdpMungingType::kAudioCodecsRtcpFb
                   : SdpMungingType::kVideoCodecsRtcpFb;
      }
      // Nonstandard a=packetization:raw added by munging
      if (media_type == MediaType::VIDEO &&
          last_created_codecs[i].packetization !=
              codecs_to_set[i].packetization) {
        return SdpMungingType::kVideoCodecsModifiedWithRawPacketization;
      }
      // At this point clockrate or channels changed. This should already be
      // rejected later in the process so ignore for munging.
    }
  }
  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineVideoSdpModification(
    const MediaContentDescription* last_created_media_description,
    const MediaContentDescription* media_description_to_set) {
  RTC_DCHECK(last_created_media_description);
  RTC_DCHECK(media_description_to_set);
  // Removing codecs should be done via setCodecPreferences or negotiation, not
  // munging.
  if (last_created_media_description->codecs().size() >
      media_description_to_set->codecs().size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: video codecs removed.";
    return SdpMungingType::kVideoCodecsRemoved;
  }
  if (last_created_media_description->codecs().size() <
      media_description_to_set->codecs().size()) {
    // Nonstandard a=packetization:raw
    bool created_raw_packetization =
        absl::c_find_if(last_created_media_description->codecs(),
                        [](const Codec codec) {
                          return codec.packetization.has_value();
                        }) != last_created_media_description->codecs().end();
    bool set_raw_packetization =
        absl::c_find_if(media_description_to_set->codecs(),
                        [](const Codec codec) {
                          return codec.packetization.has_value();
                        }) != media_description_to_set->codecs().end();
    if (!created_raw_packetization && set_raw_packetization) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: video codecs with raw packetization added.";
      return SdpMungingType::kVideoCodecsAddedWithRawPacketization;
    }
    RTC_LOG(LS_WARNING) << "SDP munging: video codecs added.";
    return SdpMungingType::kVideoCodecsAdded;
  }

  // Simulcast munging.
  if (last_created_media_description->streams().size() == 1 &&
      media_description_to_set->streams().size() == 1) {
    bool created_sim =
        absl::c_find_if(
            last_created_media_description->streams()[0].ssrc_groups,
            [](const SsrcGroup group) {
              return group.semantics == kSimSsrcGroupSemantics;
            }) !=
        last_created_media_description->streams()[0].ssrc_groups.end();
    bool set_sim =
        absl::c_find_if(media_description_to_set->streams()[0].ssrc_groups,
                        [](const SsrcGroup group) {
                          return group.semantics == kSimSsrcGroupSemantics;
                        }) !=
        media_description_to_set->streams()[0].ssrc_groups.end();
    if (!created_sim && set_sim) {
      RTC_LOG(LS_WARNING) << "SDP munging: legacy simulcast group created.";
      return SdpMungingType::kVideoCodecsLegacySimulcast;
    }
  }

  // sps-pps-idr-in-keyframe.
  bool created_sps_pps_idr_in_keyframe =
      absl::c_find_if(last_created_media_description->codecs(),
                      [](const Codec codec) {
                        std::string value;
                        return codec.name == kH264CodecName &&
                               codec.GetParam(kH264FmtpSpsPpsIdrInKeyframe,
                                              &value) &&
                               value == kParamValueTrue;
                      }) != last_created_media_description->codecs().end();
  bool set_sps_pps_idr_in_keyframe =
      absl::c_find_if(
          media_description_to_set->codecs(), [](const Codec codec) {
            std::string value;
            return codec.name == kH264CodecName &&
                   codec.GetParam(kH264FmtpSpsPpsIdrInKeyframe, &value) &&
                   value == kParamValueTrue;
          }) != media_description_to_set->codecs().end();
  if (!created_sps_pps_idr_in_keyframe && set_sps_pps_idr_in_keyframe) {
    RTC_LOG(LS_WARNING) << "SDP munging: sps-pps-idr-in-keyframe enabled.";
    return SdpMungingType::kVideoCodecsFmtpH264SpsPpsIdrInKeyframe;
  }
  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineDataSdpModification(
    const MediaContentDescription* last_created_media_description,
    const MediaContentDescription* media_description_to_set) {
  RTC_DCHECK(last_created_media_description);
  RTC_DCHECK(media_description_to_set);
  auto last_created_sctp_description =
      last_created_media_description->as_sctp();
  auto sctp_description_to_set = media_description_to_set->as_sctp();
  RTC_DCHECK(last_created_sctp_description);
  RTC_DCHECK(sctp_description_to_set);

  if (last_created_sctp_description->sctp_init() !=
      sctp_description_to_set->sctp_init()) {
    RTC_LOG(LS_ERROR) << "SDP munging: sctp-init does not match "
                         "last created description.";
    return SdpMungingType::kDataChannelSctpInit;
  }

  if (last_created_sctp_description->max_message_size() !=
      sctp_description_to_set->max_message_size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: max-message-size does not match "
                           "last created description.";
    return SdpMungingType::kDataChannelMaxMessageSize;
  }

  if (last_created_sctp_description->port() !=
      sctp_description_to_set->port()) {
    RTC_LOG(LS_WARNING) << "SDP munging: sctp-port does not match "
                           "last created description.";
    return SdpMungingType::kDataChannelSctpPort;
  }

  return SdpMungingType::kNoModification;
}

SdpMungingType DetermineContentsModification(
    const ContentInfos& last_created_contents,
    const ContentInfos& contents_to_set) {
  SdpMungingType type;
  if (last_created_contents.size() != contents_to_set.size()) {
    RTC_LOG(LS_ERROR) << "SDP munging: Number of m= sections does not match "
                         "last created description.";
    return SdpMungingType::kNumberOfContents;
  }

  for (size_t content_index = 0; content_index < last_created_contents.size();
       content_index++) {
    // TODO: crbug.com/40567530 - more checks are needed here.
    if (last_created_contents[content_index].mid() !=
        contents_to_set[content_index].mid()) {
      RTC_LOG(LS_WARNING) << "SDP munging: mid does not match "
                             "last created description.";
      return SdpMungingType::kMid;
    }

    // Rejecting (or unrejecting) an m= section should be done via negotiation,
    // not munging.
    if (last_created_contents[content_index].rejected !=
        contents_to_set[content_index].rejected) {
      RTC_LOG(LS_WARNING) << "SDP munging: m= section rejected state does not "
                             "match last created description.";
      return SdpMungingType::kRejected;
    }

    auto* last_created_media_description =
        last_created_contents[content_index].media_description();
    auto* media_description_to_set =
        contents_to_set[content_index].media_description();
    if (!(last_created_media_description && media_description_to_set)) {
      continue;
    }
    // Validate video and audio contents.
    MediaType media_type = last_created_media_description->type();
    if (media_type == MediaType::DATA) {
      type = DetermineDataSdpModification(last_created_media_description,
                                          media_description_to_set);
      if (type != SdpMungingType::kNoModification) {
        return type;
      }
    }
    bool is_rtp =
        media_type == MediaType::AUDIO || media_type == MediaType::VIDEO;
    if (!is_rtp) {
      // The checks that follow only apply for RTP-based contents.
      continue;
    }
    if (media_type == MediaType::VIDEO) {
      type = DetermineVideoSdpModification(last_created_media_description,
                                           media_description_to_set);
      if (type != SdpMungingType::kNoModification) {
        return type;
      }
    } else if (media_type == MediaType::AUDIO) {
      type = DetermineAudioSdpModification(last_created_media_description,
                                           media_description_to_set);
      if (type != SdpMungingType::kNoModification) {
        return type;
      }
    }

    type = DetermineRtcpModification(last_created_media_description,
                                     media_description_to_set);
    if (type != SdpMungingType::kNoModification) {
      return type;
    }

    type = DetermineCodecModification(last_created_media_description,
                                      media_description_to_set);
    if (type != SdpMungingType::kNoModification) {
      return type;
    }

    // Validate direction (sendrecv et al).
    if (last_created_media_description->direction() !=
        media_description_to_set->direction()) {
      RTC_LOG(LS_WARNING) << "SDP munging: transceiver direction modified.";
      return SdpMungingType::kDirection;
    }

    // Validate Sframe attribute.
    if (last_created_media_description->sframe_enabled() !=
        media_description_to_set->sframe_enabled()) {
      RTC_LOG(LS_ERROR) << "SDP munging: sframe attribute modified.";
      return SdpMungingType::kSframe;
    }

    // Validate media streams.
    if (last_created_media_description->streams().size() !=
        media_description_to_set->streams().size()) {
      RTC_LOG(LS_WARNING) << "SDP munging: streams size does not match last "
                             "created description.";
      return SdpMungingType::kSsrcs;
    }
    for (size_t i = 0; i < last_created_media_description->streams().size();
         i++) {
      // ssrcs, then stream and track ids.
      const StreamParams& created_stream_params =
          last_created_media_description->streams()[i];
      const StreamParams& set_stream_params =
          media_description_to_set->streams()[i];
      if (last_created_media_description->streams()[i].ssrcs !=
          media_description_to_set->streams()[i].ssrcs) {
        RTC_LOG(LS_WARNING)
            << "SDP munging: SSRCs do not match last created description.";
        return SdpMungingType::kSsrcs;
      }
      if (created_stream_params.stream_ids() !=
          set_stream_params.stream_ids()) {
        RTC_LOG(LS_WARNING) << "SDP munging: msid stream modified.";
        return SdpMungingType::kMsidStream;
      }
      if (created_stream_params.id != set_stream_params.id) {
        RTC_LOG(LS_WARNING) << "SDP munging: msid track (deprecated) modified.";
        return SdpMungingType::kMsidTrack;
      }
    }

    // Validate RTP header extensions.
    auto last_created_extensions =
        last_created_media_description->rtp_header_extensions();
    auto extensions_to_set = media_description_to_set->rtp_header_extensions();
    if (last_created_extensions.size() < extensions_to_set.size()) {
      RTC_LOG(LS_WARNING) << "SDP munging: RTP header extension added.";
      return SdpMungingType::kRtpHeaderExtensionAdded;
    }
    if (last_created_extensions.size() > extensions_to_set.size()) {
      RTC_LOG(LS_WARNING) << "SDP munging: RTP header extension removed.";
      return SdpMungingType::kRtpHeaderExtensionRemoved;
    }
    for (size_t i = 0; i < last_created_extensions.size(); i++) {
      if (!(last_created_extensions[i].id == extensions_to_set[i].id)) {
        RTC_LOG(LS_WARNING) << "SDP munging: header extension modified.";
        return SdpMungingType::kRtpHeaderExtensionModified;
      }
    }

    // Validate media level cryptex.
    if (last_created_media_description->cryptex() !=
        media_description_to_set->cryptex()) {
      RTC_LOG(LS_WARNING) << "SDP munging: cryptex changed at media level.";
      return SdpMungingType::kCryptex;
    }

    // Validate b= (which does not have an effect in the local description).
    if (last_created_media_description->bandwidth() !=
        media_description_to_set->bandwidth()) {
      RTC_LOG(LS_WARNING) << "SDP munging: modifying bandwidth in SLD does not "
                             "have an effect locally.";
      return SdpMungingType::kBandwidth;
    }
  }
  return SdpMungingType::kNoModification;
}

}  // namespace

// Determine if the SDP was modified between createOffer and
// setLocalDescription.
SdpMungingType DetermineSdpMungingType(
    const SessionDescriptionInterface* sdesc,
    const SessionDescriptionInterface* last_created_desc) {
  if (!sdesc || !sdesc->description()) {
    RTC_LOG(LS_WARNING) << "SDP munging: Failed to parse session description.";
    // This is done to ensure the pointers are valid and should not happen at
    // this point.
    RTC_DCHECK_NOTREACHED();
    return SdpMungingType::kCurrentDescriptionFailedToParse;
  }

  if (!last_created_desc || !last_created_desc->description()) {
    RTC_LOG(LS_WARNING) << "SDP munging: SetLocalDescription called without "
                           "CreateOffer or CreateAnswer.";
    if (sdesc->GetType() == SdpType::kOffer) {
      return SdpMungingType::kWithoutCreateOffer;
    } else {  // answer or pranswer.
      return SdpMungingType::kWithoutCreateAnswer;
    }
  }

  // TODO: crbug.com/40567530 - we currently allow answer->pranswer
  // so can not check sdesc->GetType() == last_created_desc->GetType().

  SdpMungingType type;

  // TODO: crbug.com/40567530 - change Chromium so that pointer comparison works
  // at least for implicit local description.
  if (sdesc->description() == last_created_desc->description()) {
    return SdpMungingType::kNoModification;
  }

  // Validate contents.
  type = DetermineContentsModification(
      last_created_desc->description()->contents(),
      sdesc->description()->contents());
  if (type != SdpMungingType::kNoModification) {
    return type;
  }

  // Validate transport descriptions.
  type = DetermineTransportModification(
      last_created_desc->description()->transport_infos(),
      sdesc->description()->transport_infos());
  if (type != SdpMungingType::kNoModification) {
    return type;
  }

  // Validate number of candidates.
  for (size_t content_index = 0;
       content_index < last_created_desc->description()->contents().size();
       content_index++) {
    // All contents have a (possibly empty) candidate set.
    // Check that this holds.
    RTC_DCHECK(sdesc->candidates(content_index));
    if (sdesc->candidates(content_index)->count() !=
        last_created_desc->candidates(content_index)->count()) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: media section " << content_index << " changed from "
          << last_created_desc->candidates(content_index)->count() << " to "
          << sdesc->candidates(content_index)->count() << " candidates";
      return SdpMungingType::kIceCandidateCount;
    }
  }

  // Validate Bundle fields
  std::vector<const ContentGroup*> old_bundles =
      last_created_desc->description()->GetGroupsByName(GROUP_TYPE_BUNDLE);
  std::vector<const ContentGroup*> new_bundles =
      sdesc->description()->GetGroupsByName(GROUP_TYPE_BUNDLE);
  if (old_bundles.size() != new_bundles.size()) {
    RTC_LOG(LS_WARNING) << "SDP munging: number of bundle groups changed from "
                        << old_bundles.size() << " to " << new_bundles.size();
    return SdpMungingType::kBundle;
  }
  for (size_t i = 0; i < old_bundles.size(); ++i) {
    if (*new_bundles[i] != *old_bundles[i]) {
      RTC_LOG(LS_WARNING) << "SDP munging: Content of bundle group " << i
                          << " changed from " << old_bundles[i]->ToString()
                          << " to " << new_bundles[i]->ToString();
      return SdpMungingType::kBundle;
    }
  }

  // Validate cryptex setting.
  if (sdesc->description()->cryptex() !=
      last_created_desc->description()->cryptex()) {
    RTC_LOG(LS_WARNING) << "SDP munging: cryptex changed at session level.";
    return SdpMungingType::kCryptex;
  }

  // TODO: crbug.com/40567530 - this serializes the descriptions back to a SDP
  // string which is very complex and we not should be be forced to rely on
  // string equality.
  std::string serialized_description;
  std::string serialized_last_description;
  if (sdesc->ToString(&serialized_description) &&
      last_created_desc->ToString(&serialized_last_description) &&
      serialized_description == serialized_last_description) {
    return SdpMungingType::kNoModification;
  }
  return SdpMungingType::kUnknownModification;
}

// Similar to DetermineSdpMungingType, but only checks whether the ICE ufrag or
// pwd of the SDP has been modified between createOffer and setLocalDescription.
bool HasUfragSdpMunging(const SessionDescriptionInterface* sdesc,
                        const SessionDescriptionInterface* last_created_desc) {
  if (!sdesc || !sdesc->description()) {
    RTC_LOG(LS_WARNING) << "SDP munging: Failed to parse session description.";
    return false;
  }

  if (!last_created_desc || !last_created_desc->description()) {
    RTC_LOG(LS_WARNING) << "SDP munging: SetLocalDescription called without "
                           "CreateOffer or CreateAnswer.";
    return false;
  }
  TransportInfos last_created_transport_infos =
      last_created_desc->description()->transport_infos();
  TransportInfos transport_infos_to_set =
      sdesc->description()->transport_infos();
  for (size_t i = 0; i < std::min(last_created_transport_infos.size(),
                                  transport_infos_to_set.size());
       i++) {
    if (last_created_transport_infos[i].description.ice_ufrag !=
        transport_infos_to_set[i].description.ice_ufrag) {
      return true;
    }
    if (last_created_transport_infos[i].description.ice_pwd !=
        transport_infos_to_set[i].description.ice_pwd) {
      return true;
    }
  }
  return false;
}

bool IsSdpMungingAllowed(SdpMungingType sdp_munging_type,
                         const FieldTrialsView& trials) {
  switch (sdp_munging_type) {
    case SdpMungingType::kNoModification:
      return true;
    case SdpMungingType::kNumberOfContents:
      return false;
    case SdpMungingType::kSframe:
      return false;
    case SdpMungingType::kDataChannelSctpInit:
    case SdpMungingType::kIceOptionsSped:
      return false;
    case SdpMungingType::kCryptex:
      return false;
    case SdpMungingType::kRtcpXrRcvrRtt:
      return false;
    default:
      // Handled below.
      break;
  }
  std::string type_as_string =
      std::to_string(static_cast<int>(sdp_munging_type));

  std::string trial;
  // NoSdpMangleReject is for rollout, disallowing specific types of munging
  // via Finch. It is a comma-separated list of SdpMungingTypes
  if (trials.IsEnabled("WebRTC-NoSdpMangleReject")) {
    trial = trials.Lookup("WebRTC-NoSdpMangleReject");
    const std::vector<absl::string_view> rejected_types =
        absl::StrSplit(trial, ',');
    return absl::c_find(rejected_types, type_as_string) == rejected_types.end();
  }
  // NoSdpMangleAllowForTesting is for running E2E tests which should reject
  // by default with a test-supplied list of exceptions as a comma-separated
  // list.
  if (!trials.IsEnabled("WebRTC-NoSdpMangleAllowForTesting")) {
    return true;
  }
  trial = trials.Lookup("WebRTC-NoSdpMangleAllowForTesting");
  const std::vector<absl::string_view> allowed_types =
      absl::StrSplit(trial, ',');
  return absl::c_find(allowed_types, type_as_string) != allowed_types.end();
}

}  // namespace webrtc
