/*
 *  Copyright 2015 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 WEBRTC_API_RTPPARAMETERS_H_
#define WEBRTC_API_RTPPARAMETERS_H_

#include <string>
#include <unordered_map>
#include <vector>

#include "webrtc/api/mediatypes.h"
#include "webrtc/config.h"
#include "webrtc/rtc_base/optional.h"

namespace webrtc {

// These structures are intended to mirror those defined by:
// http://draft.ortc.org/#rtcrtpdictionaries*
// Contains everything specified as of 2017 Jan 24.
//
// They are used when retrieving or modifying the parameters of an
// RtpSender/RtpReceiver, or retrieving capabilities.
//
// Note on conventions: Where ORTC may use "octet", "short" and "unsigned"
// types, we typically use "int", in keeping with our style guidelines. The
// parameter's actual valid range will be enforced when the parameters are set,
// rather than when the parameters struct is built. An exception is made for
// SSRCs, since they use the full unsigned 32-bit range, and aren't expected to
// be used for any numeric comparisons/operations.
//
// Additionally, where ORTC uses strings, we may use enums for things that have
// a fixed number of supported values. However, for things that can be extended
// (such as codecs, by providing an external encoder factory), a string
// identifier is used.

enum class FecMechanism {
  RED,
  RED_AND_ULPFEC,
  FLEXFEC,
};

// Used in RtcpFeedback struct.
enum class RtcpFeedbackType {
  CCM,
  NACK,
  REMB,  // "goog-remb"
  TRANSPORT_CC,
};

// Used in RtcpFeedback struct when type is NACK or CCM.
enum class RtcpFeedbackMessageType {
  // Equivalent to {type: "nack", parameter: undefined} in ORTC.
  GENERIC_NACK,
  PLI,  // Usable with NACK.
  FIR,  // Usable with CCM.
};

enum class DtxStatus {
  DISABLED,
  ENABLED,
};

enum class DegradationPreference {
  MAINTAIN_FRAMERATE,
  MAINTAIN_RESOLUTION,
  BALANCED,
};

enum class PriorityType { VERY_LOW, LOW, MEDIUM, HIGH };

struct RtcpFeedback {
  RtcpFeedbackType type = RtcpFeedbackType::CCM;

  // Equivalent to ORTC "parameter" field with slight differences:
  // 1. It's an enum instead of a string.
  // 2. Generic NACK feedback is represented by a GENERIC_NACK message type,
  //    rather than an unset "parameter" value.
  rtc::Optional<RtcpFeedbackMessageType> message_type;

  // Constructors for convenience.
  RtcpFeedback() {}
  explicit RtcpFeedback(RtcpFeedbackType type) : type(type) {}
  RtcpFeedback(RtcpFeedbackType type, RtcpFeedbackMessageType message_type)
      : type(type), message_type(message_type) {}

  bool operator==(const RtcpFeedback& o) const {
    return type == o.type && message_type == o.message_type;
  }
  bool operator!=(const RtcpFeedback& o) const { return !(*this == o); }
};

// RtpCodecCapability is to RtpCodecParameters as RtpCapabilities is to
// RtpParameters. This represents the static capabilities of an endpoint's
// implementation of a codec.
struct RtpCodecCapability {
  // Build MIME "type/subtype" string from |name| and |kind|.
  std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }

  // Used to identify the codec. Equivalent to MIME subtype.
  std::string name;

  // The media type of this codec. Equivalent to MIME top-level type.
  cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;

  // Clock rate in Hertz. If unset, the codec is applicable to any clock rate.
  rtc::Optional<int> clock_rate;

  // Default payload type for this codec. Mainly needed for codecs that use
  // that have statically assigned payload types.
  rtc::Optional<int> preferred_payload_type;

  // Maximum packetization time supported by an RtpReceiver for this codec.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_ptime;

  // Preferred packetization time for an RtpReceiver or RtpSender of this
  // codec.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> ptime;

  // The number of audio channels supported. Unused for video codecs.
  rtc::Optional<int> num_channels;

  // Feedback mechanisms supported for this codec.
  std::vector<RtcpFeedback> rtcp_feedback;

  // Codec-specific parameters that must be signaled to the remote party.
  //
  // Corresponds to "a=fmtp" parameters in SDP.
  //
  // Contrary to ORTC, these parameters are named using all lowercase strings.
  // This helps make the mapping to SDP simpler, if an application is using
  // SDP. Boolean values are represented by the string "1".
  std::unordered_map<std::string, std::string> parameters;

  // Codec-specific parameters that may optionally be signaled to the remote
  // party.
  // TODO(deadbeef): Not implemented.
  std::unordered_map<std::string, std::string> options;

  // Maximum number of temporal layer extensions supported by this codec.
  // For example, a value of 1 indicates that 2 total layers are supported.
  // TODO(deadbeef): Not implemented.
  int max_temporal_layer_extensions = 0;

  // Maximum number of spatial layer extensions supported by this codec.
  // For example, a value of 1 indicates that 2 total layers are supported.
  // TODO(deadbeef): Not implemented.
  int max_spatial_layer_extensions = 0;

  // Whether the implementation can send/receive SVC layers with distinct
  // SSRCs. Always false for audio codecs. True for video codecs that support
  // scalable video coding with MRST.
  // TODO(deadbeef): Not implemented.
  bool svc_multi_stream_support = false;

  bool operator==(const RtpCodecCapability& o) const {
    return name == o.name && kind == o.kind && clock_rate == o.clock_rate &&
           preferred_payload_type == o.preferred_payload_type &&
           max_ptime == o.max_ptime && ptime == o.ptime &&
           num_channels == o.num_channels && rtcp_feedback == o.rtcp_feedback &&
           parameters == o.parameters && options == o.options &&
           max_temporal_layer_extensions == o.max_temporal_layer_extensions &&
           max_spatial_layer_extensions == o.max_spatial_layer_extensions &&
           svc_multi_stream_support == o.svc_multi_stream_support;
  }
  bool operator!=(const RtpCodecCapability& o) const { return !(*this == o); }
};

// Used in RtpCapabilities; represents the capabilities/preferences of an
// implementation for a header extension.
//
// Just called "RtpHeaderExtension" in ORTC, but the "Capability" suffix was
// added here for consistency and to avoid confusion with
// RtpHeaderExtensionParameters.
//
// Note that ORTC includes a "kind" field, but we omit this because it's
// redundant; if you call "RtpReceiver::GetCapabilities(MEDIA_TYPE_AUDIO)",
// you know you're getting audio capabilities.
struct RtpHeaderExtensionCapability {
  // URI of this extension, as defined in RFC5285.
  std::string uri;

  // Preferred value of ID that goes in the packet.
  rtc::Optional<int> preferred_id;

  // If true, it's preferred that the value in the header is encrypted.
  // TODO(deadbeef): Not implemented.
  bool preferred_encrypt = false;

  // Constructors for convenience.
  RtpHeaderExtensionCapability() = default;
  explicit RtpHeaderExtensionCapability(const std::string& uri) : uri(uri) {}
  RtpHeaderExtensionCapability(const std::string& uri, int preferred_id)
      : uri(uri), preferred_id(preferred_id) {}

  bool operator==(const RtpHeaderExtensionCapability& o) const {
    return uri == o.uri && preferred_id == o.preferred_id &&
           preferred_encrypt == o.preferred_encrypt;
  }
  bool operator!=(const RtpHeaderExtensionCapability& o) const {
    return !(*this == o);
  }
};

// See webrtc/config.h. Has "uri" and "id" fields.
// TODO(deadbeef): This is missing the "encrypt" flag, which is unimplemented.
typedef RtpExtension RtpHeaderExtensionParameters;

struct RtpFecParameters {
  // If unset, a value is chosen by the implementation.
  // Works just like RtpEncodingParameters::ssrc.
  rtc::Optional<uint32_t> ssrc;

  FecMechanism mechanism = FecMechanism::RED;

  // Constructors for convenience.
  RtpFecParameters() = default;
  explicit RtpFecParameters(FecMechanism mechanism) : mechanism(mechanism) {}
  RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
      : ssrc(ssrc), mechanism(mechanism) {}

  bool operator==(const RtpFecParameters& o) const {
    return ssrc == o.ssrc && mechanism == o.mechanism;
  }
  bool operator!=(const RtpFecParameters& o) const { return !(*this == o); }
};

struct RtpRtxParameters {
  // If unset, a value is chosen by the implementation.
  // Works just like RtpEncodingParameters::ssrc.
  rtc::Optional<uint32_t> ssrc;

  // Constructors for convenience.
  RtpRtxParameters() = default;
  explicit RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}

  bool operator==(const RtpRtxParameters& o) const { return ssrc == o.ssrc; }
  bool operator!=(const RtpRtxParameters& o) const { return !(*this == o); }
};

struct RtpEncodingParameters {
  // If unset, a value is chosen by the implementation.
  //
  // Note that the chosen value is NOT returned by GetParameters, because it
  // may change due to an SSRC conflict, in which case the conflict is handled
  // internally without any event. Another way of looking at this is that an
  // unset SSRC acts as a "wildcard" SSRC.
  rtc::Optional<uint32_t> ssrc;

  // Can be used to reference a codec in the |codecs| member of the
  // RtpParameters that contains this RtpEncodingParameters. If unset, the
  // implementation will choose the first possible codec (if a sender), or
  // prepare to receive any codec (for a receiver).
  // TODO(deadbeef): Not implemented. Implementation of RtpSender will always
  // choose the first codec from the list.
  rtc::Optional<int> codec_payload_type;

  // Specifies the FEC mechanism, if set.
  // TODO(deadbeef): Not implemented. Current implementation will use whatever
  // FEC codecs are available, including red+ulpfec.
  rtc::Optional<RtpFecParameters> fec;

  // Specifies the RTX parameters, if set.
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  rtc::Optional<RtpRtxParameters> rtx;

  // Only used for audio. If set, determines whether or not discontinuous
  // transmission will be used, if an available codec supports it. If not
  // set, the implementation default setting will be used.
  // TODO(deadbeef): Not implemented. Current implementation will use a CN
  // codec as long as it's present.
  rtc::Optional<DtxStatus> dtx;

  // The relative priority of this encoding.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<PriorityType> priority;

  // If set, this represents the Transport Independent Application Specific
  // maximum bandwidth defined in RFC3890. If unset, there is no maximum
  // bitrate.
  //
  // Just called "maxBitrate" in ORTC spec.
  //
  // TODO(deadbeef): With ORTC RtpSenders, this currently sets the total
  // bandwidth for the entire bandwidth estimator (audio and video). This is
  // just always how "b=AS" was handled, but it's not correct and should be
  // fixed.
  rtc::Optional<int> max_bitrate_bps;

  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_framerate;

  // For video, scale the resolution down by this factor.
  // TODO(deadbeef): Not implemented.
  double scale_resolution_down_by = 1.0;

  // Scale the framerate down by this factor.
  // TODO(deadbeef): Not implemented.
  double scale_framerate_down_by = 1.0;

  // For an RtpSender, set to true to cause this encoding to be sent, and false
  // for it not to be sent. For an RtpReceiver, set to true to cause the
  // encoding to be decoded, and false for it to be ignored.
  // TODO(deadbeef): Not implemented for PeerConnection RtpReceivers.
  bool active = true;

  // Value to use for RID RTP header extension.
  // Called "encodingId" in ORTC.
  // TODO(deadbeef): Not implemented.
  std::string rid;

  // RIDs of encodings on which this layer depends.
  // Called "dependencyEncodingIds" in ORTC spec.
  // TODO(deadbeef): Not implemented.
  std::vector<std::string> dependency_rids;

  bool operator==(const RtpEncodingParameters& o) const {
    return ssrc == o.ssrc && codec_payload_type == o.codec_payload_type &&
           fec == o.fec && rtx == o.rtx && dtx == o.dtx &&
           priority == o.priority && max_bitrate_bps == o.max_bitrate_bps &&
           max_framerate == o.max_framerate &&
           scale_resolution_down_by == o.scale_resolution_down_by &&
           scale_framerate_down_by == o.scale_framerate_down_by &&
           active == o.active && rid == o.rid &&
           dependency_rids == o.dependency_rids;
  }
  bool operator!=(const RtpEncodingParameters& o) const {
    return !(*this == o);
  }
};

struct RtpCodecParameters {
  // Build MIME "type/subtype" string from |name| and |kind|.
  std::string mime_type() const { return MediaTypeToString(kind) + "/" + name; }

  // Used to identify the codec. Equivalent to MIME subtype.
  std::string name;

  // The media type of this codec. Equivalent to MIME top-level type.
  cricket::MediaType kind = cricket::MEDIA_TYPE_AUDIO;

  // Payload type used to identify this codec in RTP packets.
  // This must always be present, and must be unique across all codecs using
  // the same transport.
  int payload_type = 0;

  // If unset, the implementation default is used.
  rtc::Optional<int> clock_rate;

  // The number of audio channels used. Unset for video codecs. If unset for
  // audio, the implementation default is used.
  // TODO(deadbeef): The "implementation default" part isn't fully implemented.
  // Only defaults to 1, even though some codecs (such as opus) should really
  // default to 2.
  rtc::Optional<int> num_channels;

  // The maximum packetization time to be used by an RtpSender.
  // If |ptime| is also set, this will be ignored.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> max_ptime;

  // The packetization time to be used by an RtpSender.
  // If unset, will use any time up to max_ptime.
  // TODO(deadbeef): Not implemented.
  rtc::Optional<int> ptime;

  // Feedback mechanisms to be used for this codec.
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::vector<RtcpFeedback> rtcp_feedback;

  // Codec-specific parameters that must be signaled to the remote party.
  //
  // Corresponds to "a=fmtp" parameters in SDP.
  //
  // Contrary to ORTC, these parameters are named using all lowercase strings.
  // This helps make the mapping to SDP simpler, if an application is using
  // SDP. Boolean values are represented by the string "1".
  //
  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::unordered_map<std::string, std::string> parameters;

  bool operator==(const RtpCodecParameters& o) const {
    return name == o.name && kind == o.kind && payload_type == o.payload_type &&
           clock_rate == o.clock_rate && num_channels == o.num_channels &&
           max_ptime == o.max_ptime && ptime == o.ptime &&
           rtcp_feedback == o.rtcp_feedback && parameters == o.parameters;
  }
  bool operator!=(const RtpCodecParameters& o) const { return !(*this == o); }
};

// RtpCapabilities is used to represent the static capabilities of an
// endpoint. An application can use these capabilities to construct an
// RtpParameters.
struct RtpCapabilities {
  // Supported codecs.
  std::vector<RtpCodecCapability> codecs;

  // Supported RTP header extensions.
  std::vector<RtpHeaderExtensionCapability> header_extensions;

  // Supported Forward Error Correction (FEC) mechanisms. Note that the RED,
  // ulpfec and flexfec codecs used by these mechanisms will still appear in
  // |codecs|.
  std::vector<FecMechanism> fec;

  bool operator==(const RtpCapabilities& o) const {
    return codecs == o.codecs && header_extensions == o.header_extensions &&
           fec == o.fec;
  }
  bool operator!=(const RtpCapabilities& o) const { return !(*this == o); }
};

// Note that unlike in ORTC, an RtcpParameters structure is not included in
// RtpParameters, because our API includes an additional "RtpTransport"
// abstraction on which RTCP parameters are set.
struct RtpParameters {
  // Used when calling getParameters/setParameters with a PeerConnection
  // RtpSender, to ensure that outdated parameters are not unintentionally
  // applied successfully.
  // TODO(deadbeef): Not implemented.
  std::string transaction_id;

  // Value to use for MID RTP header extension.
  // Called "muxId" in ORTC.
  // TODO(deadbeef): Not implemented.
  std::string mid;

  std::vector<RtpCodecParameters> codecs;

  // TODO(deadbeef): Not implemented with PeerConnection senders/receivers.
  std::vector<RtpHeaderExtensionParameters> header_extensions;

  std::vector<RtpEncodingParameters> encodings;

  // TODO(deadbeef): Not implemented.
  DegradationPreference degradation_preference =
      DegradationPreference::BALANCED;

  bool operator==(const RtpParameters& o) const {
    return mid == o.mid && codecs == o.codecs &&
           header_extensions == o.header_extensions &&
           encodings == o.encodings &&
           degradation_preference == o.degradation_preference;
  }
  bool operator!=(const RtpParameters& o) const { return !(*this == o); }
};

}  // namespace webrtc

#endif  // WEBRTC_API_RTPPARAMETERS_H_
