/*
 *  Copyright 2017 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_JSEP_TRANSPORT_CONTROLLER_H_
#define PC_JSEP_TRANSPORT_CONTROLLER_H_

#include <stdint.h>

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

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/async_dns_resolver.h"
#include "api/candidate.h"
#include "api/crypto/crypto_options.h"
#include "api/environment/environment.h"
#include "api/ice_transport_interface.h"
#include "api/jsep.h"
#include "api/local_network_access_permission.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_transport_factory.h"
#include "api/scoped_refptr.h"
#include "api/sequence_checker.h"
#include "api/task_queue/pending_task_safety_flag.h"
#include "api/task_queue/task_queue_base.h"
#include "api/transport/data_channel_transport_interface.h"
#include "api/transport/ecn_marking.h"
#include "api/transport/sctp_transport_factory_interface.h"
#include "api/units/timestamp.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/packet_transport_internal.h"
#include "p2p/base/port.h"
#include "p2p/base/port_allocator.h"
#include "p2p/base/transport_description.h"
#include "p2p/base/transport_info.h"
#include "p2p/dtls/dtls_transport_factory.h"
#include "p2p/dtls/dtls_transport_internal.h"
#include "pc/dtls_srtp_transport.h"
#include "pc/dtls_transport.h"
#include "pc/jsep_transport.h"
#include "pc/jsep_transport_collection.h"
#include "pc/rtp_transport.h"
#include "pc/rtp_transport_internal.h"
#include "pc/sctp_transport.h"
#include "pc/session_description.h"
#include "pc/transport_stats.h"
#include "rtc_base/containers/flat_map.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/rtc_certificate.h"
#include "rtc_base/ssl_certificate.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/thread.h"
#include "rtc_base/thread_annotations.h"

namespace webrtc {

class JsepTransportController final {
 public:
  // Used when the RtpTransport/DtlsTransport of the m= section is changed
  // because the section is rejected or BUNDLE is enabled.
  class Observer {
   public:
    virtual ~Observer() {}

    // Returns true if media associated with `mid` was successfully set up to be
    // demultiplexed on `rtp_transport`. Could return false if two bundled m=
    // sections use the same SSRC, for example.
    //
    // If a data channel transport must be negotiated, `data_channel_transport`
    // and `negotiation_state` indicate negotiation status.  If
    // `data_channel_transport` is null, the data channel transport should not
    // be used.  Otherwise, the value is a pointer to the transport to be used
    // for data channels on `mid`, if any.
    //
    // The observer should not send data on `data_channel_transport` until
    // `negotiation_state` is provisional or final.  It should not delete
    // `data_channel_transport` or any fallback transport until
    // `negotiation_state` is final.
    virtual bool OnTransportChanged(
        absl::string_view mid,
        RtpTransportInternal* rtp_transport,
        scoped_refptr<DtlsTransport> dtls_transport,
        DataChannelTransportInterface* data_channel_transport) = 0;
  };

  struct Config {
    // If `redetermine_role_on_ice_restart` is true, ICE role is redetermined
    // upon setting a local transport description that indicates an ICE
    // restart.
    bool redetermine_role_on_ice_restart = true;
    SSLProtocolVersion ssl_max_version = SSL_PROTOCOL_DTLS_12;
    // `crypto_options` is used to determine if created DTLS transports
    // negotiate GCM crypto suites or not.
    CryptoOptions crypto_options;
    PeerConnectionInterface::BundlePolicy bundle_policy =
        PeerConnectionInterface::kBundlePolicyBalanced;
    PeerConnectionInterface::RtcpMuxPolicy rtcp_mux_policy =
        PeerConnectionInterface::kRtcpMuxPolicyRequire;
    bool disable_encryption = false;
    // Used to inject the ICE/DTLS/SRTP transports created externally.
    IceTransportFactory* ice_transport_factory = nullptr;
    DtlsTransportFactory* dtls_transport_factory = nullptr;
    RtpTransportFactory* rtp_transport_factory = nullptr;
    Observer* transport_observer = nullptr;
    // Must be provided and valid for the lifetime of the
    // JsepTransportController instance.
    absl::AnyInvocable<void(const CopyOnWriteBuffer& packet,
                            int64_t packet_time_us) const>
        rtcp_handler;
    absl::AnyInvocable<void(const RtpPacketReceived& parsed_packet) const>
        un_demuxable_packet_handler;

    // Factory for SCTP transports.
    SctpTransportFactoryInterface* sctp_factory = nullptr;
    absl::AnyInvocable<void(SSLHandshakeError) const> on_dtls_handshake_error =
        [](SSLHandshakeError s) {};
    absl::AnyInvocable<void(absl::string_view, const std::vector<Candidate>&)
                           const>
        signal_ice_candidates_gathered =
            [](absl::string_view, const std::vector<Candidate>&) {};
    absl::AnyInvocable<void(IceConnectionState) const>
        signal_ice_connection_state = [](IceConnectionState) {};
    absl::AnyInvocable<void(PeerConnectionInterface::PeerConnectionState) const>
        signal_connection_state =
            [](PeerConnectionInterface::PeerConnectionState) {};
    absl::AnyInvocable<void(PeerConnectionInterface::IceConnectionState) const>
        signal_standardized_ice_connection_state =
            [](PeerConnectionInterface::IceConnectionState) {};
    absl::AnyInvocable<void(webrtc::IceGatheringState) const>
        signal_ice_gathering_state = [](webrtc::IceGatheringState) {};
    absl::AnyInvocable<void(const webrtc::IceCandidateErrorEvent&) const>
        signal_ice_candidate_error =
            [](const webrtc::IceCandidateErrorEvent&) {};
    absl::AnyInvocable<void(IceTransportInternal*,
                            const std::vector<webrtc::Candidate>&) const>
        signal_ice_candidates_removed =
            [](IceTransportInternal*, const std::vector<webrtc::Candidate>&) {};
    absl::AnyInvocable<void(const webrtc::CandidatePairChangeEvent&) const>
        signal_ice_candidate_pair_changed =
            [](const webrtc::CandidatePairChangeEvent&) {};
  };

  struct TransportState {
    std::optional<SSLRole> dtls_role;
    bool needs_ice_restart = false;
  };

  // The ICE related events are fired on the `network_thread`.
  // All the transport related methods are called on the `network_thread`
  // and destruction of the JsepTransportController must occur on the
  // `network_thread`.
  JsepTransportController(
      const Environment& env,
      TaskQueueBase* signaling_thread,
      Thread* network_thread,
      PortAllocator* port_allocator,
      AsyncDnsResolverFactoryInterface* async_dns_resolver_factory,
      LocalNetworkAccessPermissionFactoryInterface* lna_permission_factory,
      Config config);
  ~JsepTransportController();

  JsepTransportController(const JsepTransportController&) = delete;
  JsepTransportController& operator=(const JsepTransportController&) = delete;

  // The main method to be called; applies a description at the transport
  // level, creating/destroying transport objects as needed and updating their
  // properties. This includes RTP, DTLS, and ICE (but not SCTP). At least not
  // yet? May make sense to in the future.
  //
  // `local_desc` must always be valid. If a remote description has previously
  // been set via a call to `SetRemoteDescription()` then `remote_desc` should
  // point to that description object in order to keep the current local and
  // remote session descriptions in sync.
  //
  // Must be called on the signaling thread.
  RTCError SetLocalDescription(SdpType type,
                               const SessionDescription* local_desc,
                               const SessionDescription* remote_desc);

  // Call to apply a remote description (See `SetLocalDescription()` for local).
  //
  // `remote_desc` must always be valid. If a local description has previously
  // been set via a call to `SetLocalDescription()` then `local_desc` should
  // point to that description object in order to keep the current local and
  // remote session descriptions in sync.
  //
  // Must be called on the signaling thread.
  RTCError SetRemoteDescription(SdpType type,
                                const SessionDescription* local_desc,
                                const SessionDescription* remote_desc);

  // Get transports to be used for the provided `mid`. If bundling is enabled,
  // calling GetRtpTransport for multiple MIDs may yield the same object.
  RtpTransportInternal* GetRtpTransport(absl::string_view mid) const;
  DtlsTransportInternal* GetDtlsTransport(absl::string_view mid);
  // Gets the externally sharable version of the DtlsTransport.
  scoped_refptr<DtlsTransport> LookupDtlsTransportByMid_n(
      absl::string_view mid);
  scoped_refptr<DtlsTransport> LookupDtlsTransportByMid(absl::string_view mid);
  scoped_refptr<SctpTransport> GetSctpTransport(absl::string_view mid) const;

  DataChannelTransportInterface* GetDataChannelTransport(
      absl::string_view mid) const;

  /*********************
   * ICE-related methods
   ********************/
  // This method is public to allow PeerConnection to update it from
  // SetConfiguration.
  void SetIceConfig(const IceConfig& config);
  // Set the "needs-ice-restart" flag as described in JSEP. After the flag is
  // set, offers should generate new ufrags/passwords until an ICE restart
  // occurs.
  void SetNeedsIceRestartFlag();
  // Returns true if the ICE restart flag above was set, and no ICE restart has
  // occurred yet for this transport (by applying a local description with
  // changed ufrag/password). If the transport has been deleted as a result of
  // bundling, returns false.
  //
  // Must be called on the signaling thread.
  bool NeedsIceRestart(absl::string_view mid) const;
  // Start gathering candidates for any new transports, or transports doing an
  // ICE restart. Returns the pooled ICE credentials from the port allocator.
  //
  // Must be called on the signaling thread.
  std::vector<IceParameters> MaybeStartGathering();
  RTCError AddRemoteCandidates(absl::string_view mid,
                               const std::vector<Candidate>& candidates);
  // Must be called on the signaling thread.
  bool RemoveRemoteCandidate(const IceCandidate* candidate);

  /**********************
   * DTLS-related methods
   *********************/
  // Specifies the identity to use in this session.
  // Can only be called once.
  //
  // Must be called on the signaling thread.
  bool SetLocalCertificate(const scoped_refptr<RTCCertificate>& certificate);
  scoped_refptr<RTCCertificate> GetLocalCertificate(
      absl::string_view mid) const;
  // Caller owns returned certificate chain. This method mainly exists for
  // stats reporting.
  std::unique_ptr<SSLCertChain> GetRemoteSSLCertChain(
      absl::string_view mid) const;
  // Get negotiated role, if one has been negotiated.
  //
  // Must be called on the signaling thread.
  std::optional<SSLRole> GetDtlsRole(absl::string_view mid) const;

  // Must be called on the signaling thread.
  void SetTransportStates(flat_map<std::string, TransportState> states);

  // Must be called on the network thread.
  flat_map<std::string, TransportState> GetTransportStates_n();

  bool GetStats(absl::string_view transport_name, TransportStats* stats) const;

  // Must be called on the signaling thread.
  RTCError RollbackTransports();

  // Must be called on the signaling thread.
  absl::AnyInvocable<void() &&> MakeCloseTask();

 private:
  // Always called via a blocking call from the signaling thread.
  RTCError SetLocalDescription_n(SdpType type,
                                 const SessionDescription* local_desc,
                                 const SessionDescription* remote_desc)
      RTC_RUN_ON(network_thread_);

  // Always called via a blocking call from the signaling thread.
  RTCError SetRemoteDescription_n(SdpType type,
                                  const SessionDescription* local_desc,
                                  const SessionDescription* remote_desc)
      RTC_RUN_ON(network_thread_);

  // Always called via a blocking call from the signaling thread.
  bool RemoveRemoteCandidate_n(const IceCandidate* candidate)
      RTC_RUN_ON(network_thread_);

  // Always called via a blocking call from the signaling thread.
  RTCError RollbackTransports_n() RTC_RUN_ON(network_thread_);

  // Always called via a blocking call from the signaling thread.
  void MaybeStartGathering_n() RTC_RUN_ON(network_thread_);

  // Always called via a blocking call from the signaling thread.
  bool SetLocalCertificate_n(const scoped_refptr<RTCCertificate>& certificate)
      RTC_RUN_ON(network_thread_);

  // Called from SetLocalDescription and SetRemoteDescription.
  // When `local` is true, local_desc must be valid. Similarly when
  // `local` is false, remote_desc must be valid. The description counterpart
  // to the one that's being applied, may be nullptr but when it's supplied
  // the counterpart description's content groups will  be kept up to date for
  // `type == SdpType::kAnswer`.
  RTCError ApplyDescription_n(bool local,
                              SdpType type,
                              const SessionDescription* local_desc,
                              const SessionDescription* remote_desc)
      RTC_RUN_ON(network_thread_);

  RTCError ValidateAndMaybeUpdateBundleGroups(
      bool local,
      SdpType type,
      const SessionDescription* local_desc,
      const SessionDescription* remote_desc) RTC_RUN_ON(network_thread_);
  RTCError ValidateContent(const ContentInfo& content_info);

  void HandleRejectedContent(const ContentInfo& content_info)
      RTC_RUN_ON(network_thread_);
  bool HandleBundledContent(const ContentInfo& content_info,
                            const ContentGroup& bundle_group)
      RTC_RUN_ON(network_thread_);

  JsepTransportDescription CreateJsepTransportDescription(
      const ContentInfo& content_info,
      const TransportInfo& transport_info,
      const std::vector<int>& encrypted_extension_ids);

  std::map<const ContentGroup*, std::vector<int>>
  MergeEncryptedHeaderExtensionIdsForBundles(
      const SessionDescription* description);
  std::vector<int> GetEncryptedHeaderExtensionIds(
      const ContentInfo& content_info);

  // This method takes the BUNDLE group into account. If the JsepTransport is
  // destroyed because of BUNDLE, it would return the transport which other
  // transports are bundled on (In current implementation, it is the first
  // content in the BUNDLE group).
  const JsepTransport* GetJsepTransportForMid(absl::string_view mid) const
      RTC_RUN_ON(network_thread_);
  JsepTransport* GetJsepTransportForMid(absl::string_view mid)
      RTC_RUN_ON(network_thread_);

  // Get the JsepTransport without considering the BUNDLE group. Return nullptr
  // if the JsepTransport is destroyed.
  const JsepTransport* GetJsepTransportByName(
      absl::string_view transport_name) const RTC_RUN_ON(network_thread_);
  JsepTransport* GetJsepTransportByName(absl::string_view transport_name)
      RTC_RUN_ON(network_thread_);

  // Creates jsep transport. Noop if transport is already created.
  // Transport is created either during SetLocalDescription (`local` == true) or
  // during SetRemoteDescription (`local` == false). Passing `local` helps to
  // differentiate initiator (caller) from answerer (callee).
  RTCError MaybeCreateJsepTransport(bool local,
                                    const ContentInfo& content_info,
                                    const SessionDescription& description)
      RTC_RUN_ON(network_thread_);

  void DestroyAllJsepTransports_n() RTC_RUN_ON(network_thread_);

  void SetIceRole_n(IceRole ice_role) RTC_RUN_ON(network_thread_);

  IceRole DetermineIceRole(JsepTransport* jsep_transport,
                           const TransportInfo& transport_info,
                           SdpType type,
                           bool local);

  std::unique_ptr<DtlsTransportInternal> CreateDtlsTransport(
      const ContentInfo& content_info,
      bool rtcp);
  scoped_refptr<IceTransportInterface> CreateIceTransport(
      absl::string_view transport_name,
      bool rtcp);
  std::unique_ptr<RtpTransport> CreateUnencryptedRtpTransport(
      absl::string_view transport_name,
      std::unique_ptr<PacketTransportInternal> rtp_packet_transport,
      std::unique_ptr<PacketTransportInternal> rtcp_packet_transport);

  // Creates a DTLS SRTP transport.
  std::unique_ptr<DtlsSrtpTransport> CreateDtlsSrtpTransport(
      absl::string_view transport_name,
      std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
      std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport);

  std::unique_ptr<RtpTransport> CreateRtpTransport(
      absl::string_view transport_name,
      std::unique_ptr<DtlsTransportInternal> rtp_dtls_transport,
      std::unique_ptr<DtlsTransportInternal> rtcp_dtls_transport);

  // Collect all the DtlsTransports, including RTP and RTCP, from the
  // JsepTransports, including those not mapped to a MID because they are being
  // kept alive in case of rollback.
  std::vector<DtlsTransportInternal*> GetDtlsTransports();
  // Same as the above, but doesn't include rollback transports.
  // JsepTransportController can iterate all the DtlsTransports and update the
  // aggregate states.
  std::vector<DtlsTransportInternal*> GetActiveDtlsTransports();

  // Handlers for signals from Transport.
  void OnTransportWritableState_n(PacketTransportInternal* transport)
      RTC_RUN_ON(network_thread_);
  void OnTransportReceivingState_n(PacketTransportInternal* transport)
      RTC_RUN_ON(network_thread_);
  void OnTransportGatheringState_n(IceTransportInternal* transport)
      RTC_RUN_ON(network_thread_);
  void OnTransportCandidateGathered_n(IceTransportInternal* transport,
                                      const Candidate& candidate)
      RTC_RUN_ON(network_thread_);
  void OnTransportCandidateError_n(IceTransportInternal* transport,
                                   const IceCandidateErrorEvent& event)
      RTC_RUN_ON(network_thread_);
  void OnTransportCandidatesRemoved_n(IceTransportInternal* transport,
                                      const Candidates& candidates)
      RTC_RUN_ON(network_thread_);
  void OnTransportRoleConflict_n(IceTransportInternal* transport)
      RTC_RUN_ON(network_thread_);
  void OnDtlsRoleChange_n(DtlsTransportInternal* transport, SSLRole role)
      RTC_RUN_ON(network_thread_);
  void OnTransportStateChanged_n(IceTransportInternal* transport)
      RTC_RUN_ON(network_thread_);
  void OnTransportCandidatePairChanged_n(const CandidatePairChangeEvent& event)
      RTC_RUN_ON(network_thread_);
  void UpdateAggregateStates_n() RTC_RUN_ON(network_thread_);

  void OnRtcpPacketReceived_n(CopyOnWriteBuffer packet,
                              std::optional<Timestamp> arrival_time,
                              EcnMarking ecn) RTC_RUN_ON(network_thread_);
  void OnUnDemuxableRtpPacketReceived_n(const RtpPacketReceived& packet)
      RTC_RUN_ON(network_thread_);

  void OnDtlsHandshakeError(SSLHandshakeError error);

  bool OnTransportChanged(absl::string_view mid, JsepTransport* transport);

  const Environment env_;
  TaskQueueBase* const signaling_thread_;
  Thread* const network_thread_;
  PortAllocator* const port_allocator_ = nullptr;
  AsyncDnsResolverFactoryInterface* const async_dns_resolver_factory_ = nullptr;
  LocalNetworkAccessPermissionFactoryInterface* const lna_permission_factory_ =
      nullptr;

  JsepTransportCollection transports_ RTC_GUARDED_BY(network_thread_);
  // Aggregate states for Transports.
  // standardized_ice_connection_state_ is intended to replace
  // ice_connection_state, see bugs.webrtc.org/9308
  IceConnectionState ice_connection_state_ = kIceConnectionConnecting;
  PeerConnectionInterface::IceConnectionState
      standardized_ice_connection_state_ =
          PeerConnectionInterface::kIceConnectionNew;
  PeerConnectionInterface::PeerConnectionState combined_connection_state_ =
      PeerConnectionInterface::PeerConnectionState::kNew;
  IceGatheringState ice_gathering_state_ = kIceGatheringNew;

  const Config config_;

  IceConfig ice_config_;
  IceRole ice_role_ = ICEROLE_CONTROLLING;
  scoped_refptr<RTCCertificate> certificate_;

  BundleManager bundles_;

  flat_map<std::string, TransportState> transport_states_
      RTC_GUARDED_BY(signaling_thread_);

  scoped_refptr<PendingTaskSafetyFlag> role_update_safety_flag_s_
      RTC_GUARDED_BY(signaling_thread_);
  scoped_refptr<PendingTaskSafetyFlag> role_update_safety_flag_n_
      RTC_GUARDED_BY(network_thread_);
};

}  // namespace webrtc

#endif  // PC_JSEP_TRANSPORT_CONTROLLER_H_
