/*
 *  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++) {
    if (last_created_transport_infos[i].description.ice_ufrag !=
        transport_infos_to_set[i].description.ice_ufrag) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice-ufrag does not match last created description.";
      return SdpMungingType::kIceUfrag;
    }
    if (last_created_transport_infos[i].description.ice_pwd !=
        transport_infos_to_set[i].description.ice_pwd) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice-pwd does not match last created description.";
      return SdpMungingType::kIcePwd;
    }
    if (last_created_transport_infos[i].description.ice_mode !=
        transport_infos_to_set[i].description.ice_mode) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: ice mode does not match last created description.";
      return SdpMungingType::kIceMode;
    }
    if (last_created_transport_infos[i].description.connection_role !=
        transport_infos_to_set[i].description.connection_role) {
      RTC_LOG(LS_WARNING)
          << "SDP munging: DTLS role does not match last created description.";
      return SdpMungingType::kDtlsSetup;
    }
    if (last_created_transport_infos[i].description.transport_options !=
        transport_infos_to_set[i].description.transport_options) {
      RTC_LOG(LS_WARNING) << "SDP munging: ice_options does not match last "
                             "created description.";
      bool created_renomination =
          absl::c_find(
              last_created_transport_infos[i].description.transport_options,
              ICE_OPTION_RENOMINATION) !=
          last_created_transport_infos[i].description.transport_options.end();
      bool set_renomination =
          absl::c_find(transport_infos_to_set[i].description.transport_options,
                       ICE_OPTION_RENOMINATION) !=
          transport_infos_to_set[i].description.transport_options.end();
      if (!created_renomination && set_renomination) {
        return SdpMungingType::kIceOptionsRenomination;
      }
      bool created_trickle =
          absl::c_find(
              last_created_transport_infos[i].description.transport_options,
              ICE_OPTION_TRICKLE) !=
          last_created_transport_infos[i].description.transport_options.end();
      bool set_trickle =
          absl::c_find(transport_infos_to_set[i].description.transport_options,
                       ICE_OPTION_TRICKLE) !=
          transport_infos_to_set[i].description.transport_options.end();
      if (created_trickle && !set_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;
  }
  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;
    }

    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 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;
    }
  }

  // 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:
      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
