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

#ifndef PC_SDP_OFFER_ANSWER_H_
#define PC_SDP_OFFER_ANSWER_H_

#include <stddef.h>
#include <stdint.h>

#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/audio_options.h"
#include "api/candidate.h"
#include "api/environment/environment.h"
#include "api/jsep.h"
#include "api/media_stream_interface.h"
#include "api/media_types.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_transceiver_direction.h"
#include "api/rtp_transceiver_interface.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/set_local_description_observer_interface.h"
#include "api/set_remote_description_observer_interface.h"
#include "api/uma_metrics.h"
#include "api/video/video_bitrate_allocator_factory.h"
#include "call/payload_type.h"
#include "media/base/media_channel.h"
#include "media/base/media_engine.h"
#include "media/base/stream_params.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/transport_description.h"
#include "pc/codec_vendor.h"
#include "pc/connection_context.h"
#include "pc/data_channel_controller.h"
#include "pc/jsep_transport_controller.h"
#include "pc/media_options.h"
#include "pc/media_stream_observer.h"
#include "pc/rtp_receiver.h"
#include "pc/rtp_transceiver.h"
#include "pc/rtp_transmission_manager.h"
#include "pc/scoped_operations_batcher.h"
#include "pc/sdp_payload_type_suggester.h"
#include "pc/sdp_state_provider.h"
#include "pc/session_description.h"
#include "pc/stream_collection.h"
#include "pc/transceiver_list.h"
#include "pc/webrtc_session_description_factory.h"
#include "rtc_base/checks.h"
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/containers/flat_set.h"
#include "rtc_base/operations_chain.h"
#include "rtc_base/rtc_certificate_generator.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/system/plan_b_only.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"
#include "rtc_base/unique_id_generator.h"
#include "rtc_base/weak_ptr.h"

namespace webrtc {

class ScopedOperationsBatcher;

// SdpOfferAnswerHandler is a component
// of the PeerConnection object as defined
// by the PeerConnectionInterface API surface.
// The class is responsible for the following:
// - Parsing and interpreting SDP.
// - Generating offers and answers based on the current state.
// This class lives on the signaling thread.
class SdpOfferAnswerHandler : public SdpStateProvider {
 public:
  ~SdpOfferAnswerHandler() override;

  // Creates an SdpOfferAnswerHandler. Modifies dependencies.
  static std::unique_ptr<SdpOfferAnswerHandler> Create(
      const Environment& env,
      PeerConnectionSdpMethods* pc,
      std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator,
      std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
          video_bitrate_allocator_factory,
      ConnectionContext* context,
      CodecLookupHelper* codec_lookup_helper);

  void ResetSessionDescFactory() {
    RTC_DCHECK_RUN_ON(signaling_thread());
    webrtc_session_desc_factory_.reset();
  }
  const WebRtcSessionDescriptionFactory* webrtc_session_desc_factory() const {
    RTC_DCHECK_RUN_ON(signaling_thread());
    return webrtc_session_desc_factory_.get();
  }

  VideoBitrateAllocatorFactory* video_bitrate_allocator_factory() const {
    RTC_DCHECK_RUN_ON(signaling_thread());
    return video_bitrate_allocator_factory_.get();
  }

  const AudioOptions& audio_options() const { return audio_options_; }
  const VideoOptions& video_options() const { return video_options_; }

  // Change signaling state to Closed, and perform appropriate actions.
  void Close();

  // Called as part of destroying the owning PeerConnection.
  void PrepareForShutdown();

  // Implementation of SdpStateProvider
  PeerConnectionInterface::SignalingState signaling_state() const override;

  const SessionDescriptionInterface* local_description() const override;
  const SessionDescriptionInterface* remote_description() const override;
  const SessionDescriptionInterface* current_local_description() const override;
  const SessionDescriptionInterface* current_remote_description()
      const override;
  const SessionDescriptionInterface* pending_local_description() const override;
  const SessionDescriptionInterface* pending_remote_description()
      const override;

  bool NeedsIceRestart(const std::string& content_name) const override;
  bool IceRestartPending(const std::string& content_name) const override;
  std::optional<SSLRole> GetDtlsRole(const std::string& mid) const override;

  void RestartIce();

  // JSEP01
  void CreateOffer(
      CreateSessionDescriptionObserver* observer,
      const PeerConnectionInterface::RTCOfferAnswerOptions& options);
  void CreateAnswer(
      CreateSessionDescriptionObserver* observer,
      const PeerConnectionInterface::RTCOfferAnswerOptions& options);

  void SetLocalDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      scoped_refptr<SetLocalDescriptionObserverInterface> observer);
  void SetLocalDescription(
      scoped_refptr<SetLocalDescriptionObserverInterface> observer);
  void SetLocalDescription(
      scoped_refptr<SetSessionDescriptionObserver> observer,
      std::unique_ptr<SessionDescriptionInterface> desc);
  void SetLocalDescription(
      scoped_refptr<SetSessionDescriptionObserver> observer);

  void SetRemoteDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      scoped_refptr<SetRemoteDescriptionObserverInterface> observer);
  void SetRemoteDescription(
      scoped_refptr<SetSessionDescriptionObserver> observer,
      std::unique_ptr<SessionDescriptionInterface> desc);

  PeerConnectionInterface::RTCConfiguration GetConfiguration();
  RTCError SetConfiguration(
      const PeerConnectionInterface::RTCConfiguration& configuration);
  void UpdateCachedIceCredentials(std::vector<IceParameters> credentials);
  bool AddIceCandidate(const IceCandidate* candidate);
  void AddIceCandidate(
      std::unique_ptr<IceCandidate> candidate,
      absl::AnyInvocable<void(RTCError, absl::AnyInvocable<void() &&>) &&>
          callback);
  bool RemoveIceCandidate(const IceCandidate* candidate);
  // Adds a locally generated candidate to the local description.
  void AddLocalIceCandidate(const IceCandidate* candidate);
  void RemoveLocalIceCandidates(absl::string_view mid,
                                const std::vector<Candidate>& candidates);
  bool ShouldFireNegotiationNeededEvent(uint32_t event_id);

  PLAN_B_ONLY bool AddStream(MediaStreamInterface* local_stream);
  PLAN_B_ONLY void RemoveStream(MediaStreamInterface* local_stream);

  std::optional<bool> is_caller() const;
  bool HasNewIceCredentials();
  // Updates the negotiation needed flag and generates the onnegotiationneeded
  // event if needed. Also increments the internal state version counter, which
  // is used to invalidate cached/unapplied offers or answers when state
  // changes.
  void UpdateNegotiationNeeded();
  void AllocateSctpSids();
  // Based on the negotiation state, guess what the SSLRole might be without
  // directly getting the information from the transport.
  // This is used for allocating stream ids for data channels.
  // See also `InternalDataChannelInit::fallback_ssl_role`.
  std::optional<SSLRole> GuessSslRole() const;

  // Gathers tasks from all transceivers to tear down the state that
  // belongs to the network and worker threads.
  // The caller is responsible for invoking the callbacks on the correct threads
  // in the order 1st network thread, 2nd worker thread.
  void GetMediaChannelTeardownTasks(ScopedOperationsBatcher& network_tasks,
                                    ScopedOperationsBatcher& worker_tasks);

  PLAN_B_ONLY scoped_refptr<StreamCollectionInterface> local_streams();
  PLAN_B_ONLY scoped_refptr<StreamCollectionInterface> remote_streams();

  bool initial_offerer() {
    RTC_DCHECK_RUN_ON(signaling_thread());
    if (initial_offerer_) {
      return *initial_offerer_;
    }
    return false;
  }

  SdpMungingType sdp_munging_type() const { return last_sdp_munging_type_; }
  void DisableSdpMungingChecksForTesting() {
    disable_sdp_munging_checks_ = true;
  }
  PayloadTypeSuggester* pt_suggester() { return &pt_suggester_; }

 private:
  class RemoteDescriptionOperation;
  class ImplicitCreateSessionDescriptionObserver;

  friend class ImplicitCreateSessionDescriptionObserver;
  class CreateSessionDescriptionObserverOperationWrapper;

  friend class CreateSessionDescriptionObserverOperationWrapper;
  class SetSessionDescriptionObserverAdapter;

  friend class SetSessionDescriptionObserverAdapter;

  enum class SessionError {
    kNone,       // No error.
    kContent,    // Error in BaseChannel SetLocalContent/SetRemoteContent.
    kTransport,  // Error from the underlying transport.
  };

  // Represents the [[LocalIceCredentialsToReplace]] internal slot in the spec.
  // It makes the next CreateOffer() produce new ICE credentials even if
  // RTCOfferAnswerOptions::ice_restart is false.
  // https://w3c.github.io/webrtc-pc/#dfn-localufragstoreplace
  // TODO(hbos): When JsepTransportController/JsepTransport supports rollback,
  // move this type of logic to JsepTransportController/JsepTransport.
  class LocalIceCredentialsToReplace;

  // Only called by the Create() function.
  explicit SdpOfferAnswerHandler(const Environment& env,
                                 PeerConnectionSdpMethods* pc,
                                 ConnectionContext* context);
  // Called from the `Create()` function. Can only be called
  // once. Modifies dependencies.
  void Initialize(
      std::unique_ptr<RTCCertificateGeneratorInterface> cert_generator,
      std::unique_ptr<webrtc::VideoBitrateAllocatorFactory>
          video_bitrate_allocator_factory,
      ConnectionContext* context,
      CodecLookupHelper* codec_lookup_helper);

  Thread* signaling_thread() const;
  Thread* network_thread() const;
  // Non-const versions of local_description()/remote_description(), for use
  // internally.
  SessionDescriptionInterface* mutable_local_description()
      RTC_RUN_ON(signaling_thread()) {
    return pending_local_description_ ? pending_local_description_.get()
                                      : current_local_description_.get();
  }
  SessionDescriptionInterface* mutable_remote_description()
      RTC_RUN_ON(signaling_thread()) {
    return pending_remote_description_ ? pending_remote_description_.get()
                                       : current_remote_description_.get();
  }

  // Synchronous implementations of SetLocalDescription/SetRemoteDescription
  // that return an RTCError instead of invoking a callback.
  RTCError ApplyLocalDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid);
  void ApplyRemoteDescription(
      std::unique_ptr<RemoteDescriptionOperation> operation);

  RTCError ReplaceRemoteDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      SdpType sdp_type,
      std::unique_ptr<SessionDescriptionInterface>* replaced_description)
      RTC_RUN_ON(signaling_thread());

  // Part of ApplyRemoteDescription steps specific to Unified Plan.
  void ApplyRemoteDescriptionUpdateTransceiverState(SdpType sdp_type);

  // Updates sender SSRCs and init send encodings from transceivers.
  // Part of ApplyLocalDescription steps specific to Unified Plan.
  void UpdateSenderSsrcsFromLocalDescription() RTC_RUN_ON(signaling_thread());

  // Part of ApplyRemoteDescription steps specific to plan b.
  PLAN_B_ONLY void PlanBUpdateSendersAndReceivers(
      const ContentInfo* audio_content,
      const AudioContentDescription* audio_desc,
      const ContentInfo* video_content,
      const VideoContentDescription* video_desc);

  // Implementation of the offer/answer exchange operations. These are chained
  // onto the `operations_chain_` when the public CreateOffer(), CreateAnswer(),
  // SetLocalDescription() and SetRemoteDescription() methods are invoked.
  void DoCreateOffer(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options,
      scoped_refptr<CreateSessionDescriptionObserver> observer);
  void DoCreateAnswer(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options,
      scoped_refptr<CreateSessionDescriptionObserver> observer);
  void DoSetLocalDescription(
      std::unique_ptr<SessionDescriptionInterface> desc,
      scoped_refptr<SetLocalDescriptionObserverInterface> observer);
  void DoSetRemoteDescription(
      std::unique_ptr<RemoteDescriptionOperation> operation);

  // Fire `OnSessionDescription{Success,Failure}` for the given action through
  // the tracer if one is attached.
  void TraceCreateSessionDescriptionComplete(
      SdpType type,
      const SessionDescriptionInterface* desc,
      const RTCError& error);
  void TraceSetLocalDescriptionComplete(const RTCError& error);
  void TraceSetRemoteDescriptionComplete(const RTCError& error);

  // Called after a DoSetRemoteDescription operation completes.
  void SetRemoteDescriptionPostProcess(bool was_answer)
      RTC_RUN_ON(signaling_thread());

  // Update the state, signaling if necessary.
  void ChangeSignalingState(
      PeerConnectionInterface::SignalingState signaling_state);

  RTCError UpdateSessionState(
      SdpType type,
      ContentSource source,
      const SessionDescription* description,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid);

  bool IsUnifiedPlan() const;

  // Signals from MediaStreamObserver.
  PLAN_B_ONLY void OnAudioTrackAdded(AudioTrackInterface* track,
                                     MediaStreamInterface* stream)
      RTC_RUN_ON(signaling_thread());
  PLAN_B_ONLY void OnAudioTrackRemoved(AudioTrackInterface* track,
                                       MediaStreamInterface* stream)
      RTC_RUN_ON(signaling_thread());
  PLAN_B_ONLY void OnVideoTrackAdded(VideoTrackInterface* track,
                                     MediaStreamInterface* stream)
      RTC_RUN_ON(signaling_thread());
  PLAN_B_ONLY void OnVideoTrackRemoved(VideoTrackInterface* track,
                                       MediaStreamInterface* stream)
      RTC_RUN_ON(signaling_thread());

  // | desc_type | is the type of the description that caused the rollback.
  RTCError Rollback(SdpType desc_type);
  void OnOperationsChainEmpty();

  // Runs the algorithm **set the associated remote streams** specified in
  // https://w3c.github.io/webrtc-pc/#set-associated-remote-streams.
  void SetAssociatedRemoteStreams(
      scoped_refptr<RtpReceiverInternal> receiver,
      const std::vector<std::string>& stream_ids,
      std::vector<scoped_refptr<MediaStreamInterface>>* added_streams,
      std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams);

  bool CheckIfNegotiationIsNeeded();
  void GenerateNegotiationNeededEvent();
  // Helper method which verifies SDP.
  RTCError ValidateSessionDescription(
      const SessionDescriptionInterface* sdesc,
      ContentSource source,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid)
      RTC_RUN_ON(signaling_thread());

  // Updates the local RtpTransceivers according to the JSEP rules. Called as
  // part of setting the local/remote description.
  RTCError UpdateTransceiversAndDataChannels(
      ContentSource source,
      const SessionDescriptionInterface& new_session,
      const SessionDescriptionInterface* old_local_description,
      const SessionDescriptionInterface* old_remote_description,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid);

  // Associate the given transceiver according to the JSEP rules.
  RTCErrorOr<scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
  AssociateTransceiver(ContentSource source,
                       SdpType type,
                       size_t mline_index,
                       const ContentInfo& content,
                       const ContentInfo* old_local_content,
                       const ContentInfo* old_remote_content)
      RTC_RUN_ON(signaling_thread());

  // Returns the media section in the given session description that is
  // associated with the RtpTransceiver. Returns null if none found or this
  // RtpTransceiver is not associated. Logic varies depending on the
  // SdpSemantics specified in the configuration.
  const ContentInfo* FindMediaSectionForTransceiver(
      const RtpTransceiver* transceiver,
      const SessionDescriptionInterface* sdesc) const;

  // Either creates or destroys the transceiver's BaseChannel according to the
  // given media section.
  void UpdateTransceiverChannel(
      scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
          transceiver,
      const ContentInfo& content,
      const ContentGroup* bundle_group,
      ScopedOperationsBatcher& network_teardown_tasks,
      ScopedOperationsBatcher& worker_tasks,
      ScopedOperationsBatcher& network_init_tasks)
      RTC_RUN_ON(signaling_thread());

  // Either creates or destroys the local data channel according to the given
  // media section.
  RTCError UpdateDataChannelTransport(ContentSource source,
                                      const ContentInfo& content,
                                      const ContentGroup* bundle_group)
      RTC_RUN_ON(signaling_thread());
  // Check if a call to SetLocalDescription is acceptable with a session
  // description of the given type.
  bool ExpectSetLocalDescription(SdpType type);
  // Check if a call to SetRemoteDescription is acceptable with a session
  // description of the given type.
  bool ExpectSetRemoteDescription(SdpType type);

  // The offer/answer machinery assumes the media section MID is present and
  // unique. To support legacy end points that do not supply a=mid lines, this
  // method will modify the session description to add MIDs generated according
  // to the SDP semantics.
  void FillInMissingRemoteMids(SessionDescription* remote_description);

  // Returns an RtpTransceiver, if available, that can be used to receive the
  // given media type according to JSEP rules.
  scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
  FindAvailableTransceiverToReceive(webrtc::MediaType media_type) const;

  // Returns a MediaSessionOptions struct with options decided by `options`,
  // the local MediaStreams and DataChannels.
  void GetOptionsForOffer(const PeerConnectionInterface::RTCOfferAnswerOptions&
                              offer_answer_options,
                          MediaSessionOptions* session_options);
  PLAN_B_ONLY void GetOptionsForPlanBOffer(
      const PeerConnectionInterface::RTCOfferAnswerOptions&
          offer_answer_options,
      MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread());
  void GetOptionsForUnifiedPlanOffer(
      const PeerConnectionInterface::RTCOfferAnswerOptions&
          offer_answer_options,
      MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread());

  // Returns a MediaSessionOptions struct with options decided by
  // `constraints`, the local MediaStreams and DataChannels.
  void GetOptionsForAnswer(const PeerConnectionInterface::RTCOfferAnswerOptions&
                               offer_answer_options,
                           MediaSessionOptions* session_options);
  PLAN_B_ONLY void GetOptionsForPlanBAnswer(
      const PeerConnectionInterface::RTCOfferAnswerOptions&
          offer_answer_options,
      MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread());
  void GetOptionsForUnifiedPlanAnswer(
      const PeerConnectionInterface::RTCOfferAnswerOptions&
          offer_answer_options,
      MediaSessionOptions* session_options) RTC_RUN_ON(signaling_thread());

  const char* SessionErrorToString(SessionError error) const;
  std::string GetSessionErrorMsg();
  // Returns the last error in the session. See the enum above for details.
  SessionError session_error() const {
    RTC_DCHECK_RUN_ON(signaling_thread());
    return session_error_;
  }
  const std::string& session_error_desc() const { return session_error_desc_; }

  RTCError HandleLegacyOfferOptions(
      const PeerConnectionInterface::RTCOfferAnswerOptions& options);
  void RemoveRecvDirectionFromReceivingTransceiversOfType(
      webrtc::MediaType media_type) RTC_RUN_ON(signaling_thread());
  void AddUpToOneReceivingTransceiverOfType(webrtc::MediaType media_type);

  std::vector<scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>>
  GetReceivingTransceiversOfType(webrtc::MediaType media_type)
      RTC_RUN_ON(signaling_thread());

  // Runs the algorithm specified in
  // https://w3c.github.io/webrtc-pc/#process-remote-track-removal
  // This method will update the following lists:
  // `remove_list` is the list of transceivers for which the receiving track is
  //     being removed.
  // `removed_streams` is the list of streams which no longer have a receiving
  //     track so should be removed.
  void ProcessRemovalOfRemoteTrack(
      const scoped_refptr<RtpTransceiverProxyWithInternal<RtpTransceiver>>
          transceiver,
      std::vector<scoped_refptr<RtpTransceiverInterface>>* remove_list,
      std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams);

  void RemoveRemoteStreamsIfEmpty(
      const std::vector<scoped_refptr<MediaStreamInterface>>& remote_streams,
      std::vector<scoped_refptr<MediaStreamInterface>>* removed_streams);

  // Remove all local and remote senders of type `media_type`.
  // Called when a media type is rejected (m-line set to port 0).
  PLAN_B_ONLY void RemoveSenders(webrtc::MediaType media_type);

  // Loops through the vector of `streams` and finds added and removed
  // StreamParams since last time this method was called.
  // For each new or removed StreamParam, OnLocalSenderSeen or
  // OnLocalSenderRemoved is invoked.
  PLAN_B_ONLY void UpdateLocalSendersPlanB(
      const std::vector<StreamParams>& streams,
      webrtc::MediaType media_type);

  // Makes sure a MediaStreamTrack is created for each StreamParam in `streams`,
  // and existing MediaStreamTracks are removed if there is no corresponding
  // StreamParam. If `default_track_needed` is true, a default MediaStreamTrack
  // is created if it doesn't exist; if false, it's removed if it exists.
  // `media_type` is the type of the `streams` and can be either audio or video.
  // If a new MediaStream is created it is added to `new_streams`.
  PLAN_B_ONLY void UpdateRemoteSendersListPlanB(
      const std::vector<StreamParams>& streams,
      bool default_track_needed,
      webrtc::MediaType media_type,
      StreamCollection* new_streams);

  // Enables media channels to allow sending of media.
  // This enables media to flow on all configured audio/video channels.
  void EnableSending();
  // Push the media parts of the local or remote session description
  // down to all of the channels, and start SCTP if needed.
  RTCError PushdownMediaDescription(
      SdpType type,
      ContentSource source,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid);

  RTCError PushdownTransportDescription(ContentSource source, SdpType type);
  // Helper function to remove stopped transceivers.
  void RemoveStoppedTransceivers();
  // Deletes the corresponding channel of contents that don't exist in `desc`.
  // `desc` can be null. This means that all channels are deleted.
  void RemoveUnusedChannels(const SessionDescription* desc);

  // Finds remote MediaStreams without any tracks and removes them from
  // `remote_streams_` and notifies the observer that the MediaStreams no longer
  // exist.
  void UpdateEndedRemoteMediaStreams();

  // Uses all remote candidates in the currently set remote_description().
  // If no remote description is currently set (nullptr), the return value will
  // be true. If `UseCandidate()` fails for any candidate in the remote
  // description, the return value will be false.
  bool UseCandidatesInRemoteDescription();
  // Uses `candidate` in this session.
  bool UseCandidate(const IceCandidate* candidate);
  // Returns true if we are ready to push down the remote candidate.
  // `remote_desc` is the new remote description, or NULL if the current remote
  // description should be used. Output `valid` is true if the candidate media
  // index is valid.
  bool ReadyToUseRemoteCandidate(const IceCandidate* candidate,
                                 const SessionDescriptionInterface* remote_desc,
                                 bool* valid);

  RTCErrorOr<const ContentInfo*> FindContentInfo(
      const SessionDescriptionInterface* description,
      const IceCandidate* candidate) RTC_RUN_ON(signaling_thread());

  // Functions for dealing with transports.
  // Note that cricket code uses the term "channel" for what other code
  // refers to as "transport".

  // Allocates media channels based on the `desc`. If `desc` doesn't have
  // the BUNDLE option, this method will disable BUNDLE in PortAllocator.
  // This method will also delete any existing media channels before creating.
  PLAN_B_ONLY RTCError CreateChannels(const SessionDescription& desc);

  // Generates MediaDescriptionOptions for the `session_opts` based on existing
  // local description or remote description.
  void GenerateMediaDescriptionOptions(
      const SessionDescriptionInterface* session_desc,
      RtpTransceiverDirection audio_direction,
      RtpTransceiverDirection video_direction,
      std::optional<size_t>* audio_index,
      std::optional<size_t>* video_index,
      std::optional<size_t>* data_index,
      MediaSessionOptions* session_options);

  // Generates the active MediaDescriptionOptions for the local data channel
  // given the specified MID.
  MediaDescriptionOptions GetMediaDescriptionOptionsForActiveData(
      absl::string_view mid) const;

  // Generates the rejected MediaDescriptionOptions for the local data channel
  // given the specified MID.
  MediaDescriptionOptions GetMediaDescriptionOptionsForRejectedData(
      absl::string_view mid) const;

  // Based on number of transceivers per media type, enabled or disable
  // payload type based demuxing in the affected channels.
  void UpdatePayloadTypeDemuxingState(
      ContentSource source,
      const flat_map<std::string, const ContentGroup*>& bundle_groups_by_mid,
      ScopedOperationsBatcher& worker_tasks);

  // Updates the error state, signaling if necessary.
  void SetSessionError(SessionError error, const std::string& error_desc);

  // Implements AddIceCandidate without reporting usage, but returns the
  // particular success/error value that should be reported (and can be utilized
  // for other purposes).
  AddIceCandidateResult AddIceCandidateInternal(const IceCandidate* candidate);

  void ReportInitialSdpMunging(bool had_local_description, SdpType type);

  // Helper function to negotiate an SCTP m= line.
  void MaybeNegotiateSctp(MediaSessionOptions* session_options)
      RTC_RUN_ON(signaling_thread());

  // ==================================================================
  // Access to pc_ variables
  const MediaEngineInterface* media_engine() const;
  TransceiverList* transceivers();
  const TransceiverList* transceivers() const;
  DataChannelController* data_channel_controller();
  const DataChannelController* data_channel_controller() const;
  PortAllocator* port_allocator();
  const PortAllocator* port_allocator() const;
  RtpTransmissionManager* rtp_manager();
  const RtpTransmissionManager* rtp_manager() const;
  JsepTransportController* transport_controller_s()
      RTC_RUN_ON(signaling_thread());
  const JsepTransportController* transport_controller_s() const
      RTC_RUN_ON(signaling_thread());
  JsepTransportController* transport_controller_n()
      RTC_RUN_ON(network_thread());
  const JsepTransportController* transport_controller_n() const
      RTC_RUN_ON(network_thread());
  // ===================================================================

  bool ConfiguredForMedia() const;

  const Environment& env_;
  PeerConnectionSdpMethods* const pc_;
  ConnectionContext* const context_;

  std::unique_ptr<WebRtcSessionDescriptionFactory> webrtc_session_desc_factory_
      RTC_GUARDED_BY(signaling_thread());

  std::unique_ptr<SessionDescriptionInterface> current_local_description_
      RTC_GUARDED_BY(signaling_thread());
  std::unique_ptr<SessionDescriptionInterface> pending_local_description_
      RTC_GUARDED_BY(signaling_thread());
  std::unique_ptr<SessionDescriptionInterface> current_remote_description_
      RTC_GUARDED_BY(signaling_thread());
  std::unique_ptr<SessionDescriptionInterface> pending_remote_description_
      RTC_GUARDED_BY(signaling_thread());
  // The last generated offer and answer, cached for reuse by parameterless
  // SetLocalDescription.
  std::unique_ptr<SessionDescriptionInterface> last_created_offer_
      RTC_GUARDED_BY(signaling_thread());
  std::unique_ptr<SessionDescriptionInterface> last_created_answer_
      RTC_GUARDED_BY(signaling_thread());
  // Monotonically increasing version counter that tracks changes to the
  // PeerConnection's negotiation state.
  uint64_t state_version_ RTC_GUARDED_BY(signaling_thread()) = 0;
  // The state version at the time the last offer or answer was created.
  // Used to determine if the cached offer or answer is still valid (i.e.
  // matches the current state version).
  uint64_t last_created_offer_version_ RTC_GUARDED_BY(signaling_thread()) = 0;
  uint64_t last_created_answer_version_ RTC_GUARDED_BY(signaling_thread()) = 0;
#if RTC_DCHECK_IS_ON
  PeerConnectionInterface::RTCOfferAnswerOptions last_created_offer_options_
      RTC_GUARDED_BY(signaling_thread());
  PeerConnectionInterface::RTCOfferAnswerOptions last_created_answer_options_
      RTC_GUARDED_BY(signaling_thread());
#endif
  SdpMungingType last_sdp_munging_type_ = SdpMungingType::kNoModification;

  PeerConnectionInterface::SignalingState signaling_state_
      RTC_GUARDED_BY(signaling_thread()) = PeerConnectionInterface::kStable;

  // Whether this peer is the caller. Set when the local description is applied.
  std::optional<bool> is_caller_ RTC_GUARDED_BY(signaling_thread());

  // Streams added via AddStream.
  const scoped_refptr<StreamCollection> local_streams_
      RTC_GUARDED_BY(signaling_thread());
  // Streams created as a result of SetRemoteDescription.
  const scoped_refptr<StreamCollection> remote_streams_
      RTC_GUARDED_BY(signaling_thread());

  std::vector<std::unique_ptr<MediaStreamObserver>> stream_observers_
      RTC_GUARDED_BY(signaling_thread());

  // The operations chain is used by the offer/answer exchange methods to ensure
  // they are executed in the right order. For example, if
  // SetRemoteDescription() is invoked while CreateOffer() is still pending, the
  // SRD operation will not start until CreateOffer() has completed. See
  // https://w3c.github.io/webrtc-pc/#dfn-operations-chain.
  scoped_refptr<OperationsChain> operations_chain_
      RTC_GUARDED_BY(signaling_thread());

  // One PeerConnection has only one RTCP CNAME.
  // https://tools.ietf.org/html/draft-ietf-rtcweb-rtp-usage-26#section-4.9
  const std::string rtcp_cname_;

  // MIDs will be generated using this generator which will keep track of
  // all the MIDs that have been seen over the life of the PeerConnection.
  UniqueStringGenerator mid_generator_ RTC_GUARDED_BY(signaling_thread());

  // List of content names for which the remote side triggered an ICE restart.
  flat_set<std::string> pending_ice_restarts_
      RTC_GUARDED_BY(signaling_thread());

  std::unique_ptr<LocalIceCredentialsToReplace>
      local_ice_credentials_to_replace_ RTC_GUARDED_BY(signaling_thread());

  bool remote_peer_supports_msid_ RTC_GUARDED_BY(signaling_thread()) = false;
  bool is_negotiation_needed_ RTC_GUARDED_BY(signaling_thread()) = false;
  uint32_t negotiation_needed_event_id_ RTC_GUARDED_BY(signaling_thread()) = 0;
  bool update_negotiation_needed_on_empty_chain_
      RTC_GUARDED_BY(signaling_thread()) = false;
  // If PT demuxing is successfully negotiated one time we will allow PT
  // demuxing for the rest of the session so that PT-based apps default to PT
  // demuxing in follow-up O/A exchanges.
  bool pt_demuxing_has_been_used_audio_ RTC_GUARDED_BY(signaling_thread()) =
      false;
  bool pt_demuxing_has_been_used_video_ RTC_GUARDED_BY(signaling_thread()) =
      false;

  // In Unified Plan, if we encounter remote SDP that does not contain an a=msid
  // line we create and use a stream with a random ID for our receivers. This is
  // to support legacy endpoints that do not support the a=msid attribute (as
  // opposed to streamless tracks with "a=msid:-").
  scoped_refptr<MediaStreamInterface> missing_msid_default_stream_
      RTC_GUARDED_BY(signaling_thread());

  SessionError session_error_ RTC_GUARDED_BY(signaling_thread()) =
      SessionError::kNone;
  std::string session_error_desc_ RTC_GUARDED_BY(signaling_thread());

  // Member variables for caching global options.
  const AudioOptions audio_options_;
  const VideoOptions video_options_;
  std::vector<IceParameters> cached_pooled_ice_credentials_
      RTC_GUARDED_BY(signaling_thread());

  // A video bitrate allocator factory.
  // This can be injected using the PeerConnectionDependencies,
  // or else the CreateBuiltinVideoBitrateAllocatorFactory() will be called.
  // Note that one can still choose to override this in a MediaEngine
  // if one wants too.
  std::unique_ptr<VideoBitrateAllocatorFactory> video_bitrate_allocator_factory_
      RTC_GUARDED_BY(signaling_thread());

  // Whether we are the initial offerer on the association. This
  // determines the SSL role.
  std::optional<bool> initial_offerer_ RTC_GUARDED_BY(signaling_thread());

  // Whether SDP munging checks are enabled or not.
  // Some tests will be detected as SDP munging, so offer the option
  // to disable.
  bool disable_sdp_munging_checks_ = false;
  CodecLookupHelper* codec_lookup_helper_ = nullptr;

  // Whether the username fragment or the password of the SDP was munged.
  bool has_sdp_munged_ufrag_ = false;

  SdpPayloadTypeSuggester pt_suggester_;

  int max_sctp_streams_;

#if RTC_DCHECK_IS_ON
  // Generates a new offer in the background and structurally compares it with
  // the cached `last_created_offer_` to verify cache validity.
  void VerifyCachedOffer(absl::AnyInvocable<void() &&> on_verified)
      RTC_RUN_ON(signaling_thread());
  // Generates a new answer in the background and structurally compares it with
  // the cached `last_created_answer_` to verify cache validity.
  void VerifyCachedAnswer(absl::AnyInvocable<void() &&> on_verified)
      RTC_RUN_ON(signaling_thread());
#endif

  WeakPtrFactory<SdpOfferAnswerHandler> weak_ptr_factory_
      RTC_GUARDED_BY(signaling_thread());
};

}  // namespace webrtc

#endif  // PC_SDP_OFFER_ANSWER_H_
