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

// Option structures for MediaSession APIs.
#ifndef PC_MEDIA_OPTIONS_H_
#define PC_MEDIA_OPTIONS_H_

#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/crypto/crypto_options.h"
#include "api/media_types.h"
#include "api/rtp_parameters.h"
#include "api/rtp_transceiver_direction.h"
#include "media/base/codec.h"
#include "media/base/rid_description.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_description_factory.h"
#include "pc/simulcast_description.h"
#include "rtc_base/system/plan_b_only.h"

namespace webrtc {

// Default RTCP CNAME for unit tests.
const char kDefaultRtcpCname[] = "DefaultRtcpCname";

// Options for an RtpSender contained with an media description/"m=" section.
// Note: Spec-compliant Simulcast and legacy simulcast are mutually exclusive.
struct SenderOptions {
  std::string track_id;
  std::vector<std::string> stream_ids;
  // Use RIDs and Simulcast Layers to indicate spec-compliant Simulcast.
  std::vector<RidDescription> rids;
  SimulcastLayerList simulcast_layers;
  // Use `num_sim_layers` to indicate legacy simulcast.
  int num_sim_layers;
};

// Options for an individual media description/"m=" section.
struct MediaDescriptionOptions {
  MediaDescriptionOptions(MediaType type,
                          absl::string_view mid,
                          RtpTransceiverDirection direction,
                          bool stopped)
      : type(type), mid(mid), direction(direction), stopped(stopped) {}

  // TODO(deadbeef): When we don't support Plan B, there will only be one
  // sender per media description and this can be simplified.
  PLAN_B_ONLY void AddAudioSender(const std::string& track_id,
                                  const std::vector<std::string>& stream_ids);
  PLAN_B_ONLY void AddVideoSender(const std::string& track_id,
                                  const std::vector<std::string>& stream_ids,
                                  const std::vector<RidDescription>& rids,
                                  const SimulcastLayerList& simulcast_layers,
                                  int num_sim_layers);

  MediaType type;
  std::string mid;
  RtpTransceiverDirection direction;
  bool stopped;
  TransportOptions transport_options;
  // Note: There's no equivalent "RtpReceiverOptions" because only send
  // stream information goes in the local descriptions.
  std::vector<SenderOptions> sender_options;
  std::vector<RtpCodecCapability> codec_preferences;
  std::vector<RtpHeaderExtensionCapability> header_extensions;
  // Codecs to include in a generated offer or answer.
  // If this is used, session-level codec lists MUST be ignored.
  std::vector<Codec> codecs_to_include;
  // Whether Sframe encryption is requested for this media section.
  bool sframe_enabled = false;

 private:
  // Doesn't DCHECK on `type`.
  PLAN_B_ONLY void AddSenderInternal(const std::string& track_id,
                                     const std::vector<std::string>& stream_ids,
                                     const std::vector<RidDescription>& rids,
                                     const SimulcastLayerList& simulcast_layers,
                                     int num_sim_layers);
};

// Provides a mechanism for describing how m= sections should be generated.
// The m= section with index X will use media_description_options[X]. There
// must be an option for each existing section if creating an answer, or a
// subsequent offer.
struct MediaSessionOptions {
  MediaSessionOptions() {}

  bool has_audio() const { return HasMediaDescription(MediaType::AUDIO); }
  bool has_video() const { return HasMediaDescription(MediaType::VIDEO); }
  bool has_data() const { return HasMediaDescription(MediaType::DATA); }

  bool HasMediaDescription(MediaType type) const;

  bool vad_enabled = true;  // When disabled, removes all CN codecs from SDP.
  bool rtcp_mux_enabled = true;
  bool bundle_enabled = false;
  bool offer_extmap_allow_mixed = false;
  bool raw_packetization_for_video = false;
  std::string rtcp_cname = kDefaultRtcpCname;
  CryptoOptions crypto_options;
  // List of media description options in the same order that the media
  // descriptions will be generated.
  std::vector<MediaDescriptionOptions> media_description_options;
  std::vector<IceParameters> pooled_ice_credentials;

  // Use the draft-ietf-mmusic-sctp-sdp-03 obsolete syntax for SCTP
  // datachannels.
  // Default is true for backwards compatibility with clients that use
  // this internal interface.
  bool use_obsolete_sctp_sdp = true;

  // Parse and serialize the draft-hancke-tsvwg-snap sctp-init.
  bool use_sctp_snap = false;
};

}  //  namespace webrtc


#endif  // PC_MEDIA_OPTIONS_H_
