/*
 *  Copyright 2019 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_DATAGRAM_RTP_TRANSPORT_H_
#define PC_DATAGRAM_RTP_TRANSPORT_H_

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

#include "api/crypto/crypto_options.h"
#include "api/transport/datagram_transport_interface.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtp_header_extensions.h"
#include "p2p/base/ice_transport_internal.h"
#include "p2p/base/packet_transport_internal.h"
#include "pc/rtp_transport_internal.h"
#include "rtc_base/buffer.h"
#include "rtc_base/buffer_queue.h"
#include "rtc_base/constructor_magic.h"
#include "rtc_base/ssl_stream_adapter.h"
#include "rtc_base/stream.h"
#include "rtc_base/strings/string_builder.h"
#include "rtc_base/thread_checker.h"

namespace webrtc {

constexpr int kDatagramDtlsAdaptorComponent = -1;

// RTP transport which uses the DatagramTransportInterface to send and receive
// packets.
class DatagramRtpTransport : public RtpTransportInternal,
                             public webrtc::DatagramSinkInterface,
                             public webrtc::MediaTransportStateCallback {
 public:
  DatagramRtpTransport(
      const std::vector<webrtc::RtpExtension>& rtp_header_extensions,
      cricket::IceTransportInternal* ice_transport,
      DatagramTransportInterface* datagram_transport);

  ~DatagramRtpTransport() override;

  // =====================================================
  // Overrides for webrtc::DatagramTransportSinkInterface
  // and MediaTransportStateCallback
  // =====================================================
  void OnDatagramReceived(rtc::ArrayView<const uint8_t> data) override;

  void OnDatagramSent(webrtc::DatagramId datagram_id) override;

  void OnDatagramAcked(const webrtc::DatagramAck& ack) override;

  void OnDatagramLost(webrtc::DatagramId datagram_id) override;

  void OnStateChanged(webrtc::MediaTransportState state) override;

  // =====================================================
  // RtpTransportInternal overrides
  // =====================================================
  bool SendRtpPacket(rtc::CopyOnWriteBuffer* packet,
                     const rtc::PacketOptions& options,
                     int flags) override;

  bool SendRtcpPacket(rtc::CopyOnWriteBuffer* packet,
                      const rtc::PacketOptions& options,
                      int flags) override;

  const std::string& transport_name() const override;

  // Datagram transport always muxes RTCP.
  bool rtcp_mux_enabled() const override { return true; }
  void SetRtcpMuxEnabled(bool enable) override {}

  int SetRtpOption(rtc::Socket::Option opt, int value) override;
  int SetRtcpOption(rtc::Socket::Option opt, int value) override;

  bool IsReadyToSend() const override;

  bool IsWritable(bool rtcp) const override;

  bool IsSrtpActive() const override { return false; }

  void UpdateRtpHeaderExtensionMap(
      const cricket::RtpHeaderExtensions& header_extensions) override;

  bool RegisterRtpDemuxerSink(const RtpDemuxerCriteria& criteria,
                              RtpPacketSinkInterface* sink) override;

  bool UnregisterRtpDemuxerSink(RtpPacketSinkInterface* sink) override;

 private:
  // RTP/RTCP packet info stored for each sent packet.
  struct SentPacketInfo {
    // RTP packet info with ssrc and transport sequence number.
    SentPacketInfo(int64_t packet_id,
                   uint32_t ssrc,
                   uint16_t transport_sequence_number)
        : ssrc(ssrc),
          transport_sequence_number(transport_sequence_number),
          packet_id(packet_id) {}

    // Packet info without SSRC and transport sequence number used for RTCP
    // packets, RTP packets when transport sequence number is not provided or
    // when feedback translation is disabled.
    explicit SentPacketInfo(int64_t packet_id) : packet_id(packet_id) {}

    SentPacketInfo() = default;

    absl::optional<uint32_t> ssrc;

    // Transport sequence number (if it was provided in outgoing RTP packet).
    // It is used to re-create RTCP feedback packets from datagram ACKs.
    absl::optional<uint16_t> transport_sequence_number;

    // Packet id from rtc::PacketOptions. It is required to propagage sent
    // notification up the stack (SignalSentPacket).
    int64_t packet_id = 0;
  };

  // Finds SentPacketInfo for given |datagram_id| and removes map entry.
  // Returns false if entry was not found.
  bool GetAndRemoveSentPacketInfo(webrtc::DatagramId datagram_id,
                                  SentPacketInfo* sent_packet_info);

  // Sends datagram to datagram_transport.
  bool SendDatagram(rtc::ArrayView<const uint8_t> data,
                    webrtc::DatagramId datagram_id);

  // Propagates network route changes from ICE.
  void OnNetworkRouteChanged(absl::optional<rtc::NetworkRoute> network_route);

  rtc::ThreadChecker thread_checker_;
  cricket::IceTransportInternal* ice_transport_;
  webrtc::DatagramTransportInterface* datagram_transport_;

  RtpDemuxer rtp_demuxer_;

  MediaTransportState state_ = MediaTransportState::kPending;

  // Extension map for parsing transport sequence numbers.
  webrtc::RtpHeaderExtensionMap rtp_header_extension_map_;

  // Keeps information about sent RTP packet until they are Acked or Lost.
  std::map<webrtc::DatagramId, SentPacketInfo> sent_rtp_packet_map_;

  // Current datagram_id, incremented after each sent RTP packets.
  // Datagram id is passed to datagram transport when we send datagram and we
  // get it back in notifications about Sent, Acked and Lost datagrams.
  int64_t current_datagram_id_ = 0;

  // TODO(sukhanov): Previous nonzero timestamp is required for workaround for
  // zero timestamps received, which sometimes are received from datagram
  // transport. Investigate if we can eliminate zero timestamps.
  int64_t previous_nonzero_timestamp_us_ = 0;

  // Disable datagram to RTCP feedback translation and enable RTCP feedback
  // loop (note that having both RTCP and datagram feedback loops is
  // inefficient, but can be useful in tests and experiments).
  const bool disable_datagram_to_rtcp_feeback_translation_;
};

}  // namespace webrtc

#endif  // PC_DATAGRAM_RTP_TRANSPORT_H_
