/*
 *  Copyright (c) 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.
 */
#include "api/rtp_parameters.h"

#include <algorithm>
#include <string>
#include <tuple>
#include <utility>

#include "api/array_view.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {

const char* DegradationPreferenceToString(
    DegradationPreference degradation_preference) {
  switch (degradation_preference) {
    case DegradationPreference::DISABLED:
      return "disabled";
    case DegradationPreference::MAINTAIN_FRAMERATE:
      return "maintain-framerate";
    case DegradationPreference::MAINTAIN_RESOLUTION:
      return "maintain-resolution";
    case DegradationPreference::BALANCED:
      return "balanced";
  }
  RTC_CHECK_NOTREACHED();
}

const double kDefaultBitratePriority = 1.0;

RtcpFeedback::RtcpFeedback() = default;
RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
                           RtcpFeedbackMessageType message_type)
    : type(type), message_type(message_type) {}
RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
RtcpFeedback::~RtcpFeedback() = default;

RtpCodecCapability::RtpCodecCapability() = default;
RtpCodecCapability::~RtpCodecCapability() = default;

RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri)
    : uri(uri) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    int preferred_id)
    : uri(uri), preferred_id(preferred_id) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    int preferred_id,
    RtpTransceiverDirection direction)
    : uri(uri), preferred_id(preferred_id), direction(direction) {}
RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;

RtpExtension::RtpExtension() = default;
RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {}
RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt)
    : uri(uri), id(id), encrypt(encrypt) {}
RtpExtension::~RtpExtension() = default;

RtpFecParameters::RtpFecParameters() = default;
RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
    : mechanism(mechanism) {}
RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
    : ssrc(ssrc), mechanism(mechanism) {}
RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
RtpFecParameters::~RtpFecParameters() = default;

RtpRtxParameters::RtpRtxParameters() = default;
RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
RtpRtxParameters::~RtpRtxParameters() = default;

RtpEncodingParameters::RtpEncodingParameters() = default;
RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
    default;
RtpEncodingParameters::~RtpEncodingParameters() = default;

RtpCodecParameters::RtpCodecParameters() = default;
RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
RtpCodecParameters::~RtpCodecParameters() = default;

RtpCapabilities::RtpCapabilities() = default;
RtpCapabilities::~RtpCapabilities() = default;

RtcpParameters::RtcpParameters() = default;
RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
RtcpParameters::~RtcpParameters() = default;

RtpParameters::RtpParameters() = default;
RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
RtpParameters::~RtpParameters() = default;

std::string RtpExtension::ToString() const {
  char buf[256];
  rtc::SimpleStringBuilder sb(buf);
  sb << "{uri: " << uri;
  sb << ", id: " << id;
  if (encrypt) {
    sb << ", encrypt";
  }
  sb << '}';
  return sb.str();
}

constexpr char RtpExtension::kEncryptHeaderExtensionsUri[];
constexpr char RtpExtension::kAudioLevelUri[];
constexpr char RtpExtension::kTimestampOffsetUri[];
constexpr char RtpExtension::kAbsSendTimeUri[];
constexpr char RtpExtension::kAbsoluteCaptureTimeUri[];
constexpr char RtpExtension::kVideoRotationUri[];
constexpr char RtpExtension::kVideoContentTypeUri[];
constexpr char RtpExtension::kVideoTimingUri[];
constexpr char RtpExtension::kGenericFrameDescriptorUri00[];
constexpr char RtpExtension::kDependencyDescriptorUri[];
constexpr char RtpExtension::kVideoLayersAllocationUri[];
constexpr char RtpExtension::kTransportSequenceNumberUri[];
constexpr char RtpExtension::kTransportSequenceNumberV2Uri[];
constexpr char RtpExtension::kPlayoutDelayUri[];
constexpr char RtpExtension::kColorSpaceUri[];
constexpr char RtpExtension::kMidUri[];
constexpr char RtpExtension::kRidUri[];
constexpr char RtpExtension::kRepairedRidUri[];
constexpr char RtpExtension::kVideoFrameTrackingIdUri[];
constexpr char RtpExtension::kCsrcAudioLevelsUri[];

constexpr int RtpExtension::kMinId;
constexpr int RtpExtension::kMaxId;
constexpr int RtpExtension::kMaxValueSize;
constexpr int RtpExtension::kOneByteHeaderExtensionMaxId;
constexpr int RtpExtension::kOneByteHeaderExtensionMaxValueSize;

bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
  return uri == webrtc::RtpExtension::kAudioLevelUri ||
         uri == webrtc::RtpExtension::kAbsSendTimeUri ||
         uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
         uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
         uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
         uri == webrtc::RtpExtension::kMidUri ||
         uri == webrtc::RtpExtension::kRidUri ||
         uri == webrtc::RtpExtension::kRepairedRidUri;
}

bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
  return uri == webrtc::RtpExtension::kTimestampOffsetUri ||
         uri == webrtc::RtpExtension::kAbsSendTimeUri ||
         uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
         uri == webrtc::RtpExtension::kVideoRotationUri ||
         uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
         uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
         uri == webrtc::RtpExtension::kPlayoutDelayUri ||
         uri == webrtc::RtpExtension::kVideoContentTypeUri ||
         uri == webrtc::RtpExtension::kVideoTimingUri ||
         uri == webrtc::RtpExtension::kMidUri ||
         uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00 ||
         uri == webrtc::RtpExtension::kDependencyDescriptorUri ||
         uri == webrtc::RtpExtension::kColorSpaceUri ||
         uri == webrtc::RtpExtension::kRidUri ||
         uri == webrtc::RtpExtension::kRepairedRidUri ||
         uri == webrtc::RtpExtension::kVideoLayersAllocationUri ||
         uri == webrtc::RtpExtension::kVideoFrameTrackingIdUri;
}

bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
  return
#if defined(ENABLE_EXTERNAL_AUTH)
      // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri"
      // here and filter out later if external auth is really used in
      // srtpfilter. External auth is used by Chromium and replaces the
      // extension header value of "kAbsSendTimeUri", so it must not be
      // encrypted (which can't be done by Chromium).
      uri != webrtc::RtpExtension::kAbsSendTimeUri &&
#endif
      uri != webrtc::RtpExtension::kEncryptHeaderExtensionsUri;
}

// Returns whether a header extension with the given URI exists.
// Note: This does not differentiate between encrypted and non-encrypted
// extensions, so use with care!
static bool HeaderExtensionWithUriExists(
    const std::vector<RtpExtension>& extensions,
    absl::string_view uri) {
  for (const auto& extension : extensions) {
    if (extension.uri == uri) {
      return true;
    }
  }
  return false;
}

const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
    const std::vector<RtpExtension>& extensions,
    absl::string_view uri,
    Filter filter) {
  const webrtc::RtpExtension* fallback_extension = nullptr;
  for (const auto& extension : extensions) {
    if (extension.uri != uri) {
      continue;
    }

    switch (filter) {
      case kDiscardEncryptedExtension:
        // We only accept an unencrypted extension.
        if (!extension.encrypt) {
          return &extension;
        }
        break;

      case kPreferEncryptedExtension:
        // We prefer an encrypted extension but we can fall back to an
        // unencrypted extension.
        if (extension.encrypt) {
          return &extension;
        } else {
          fallback_extension = &extension;
        }
        break;

      case kRequireEncryptedExtension:
        // We only accept an encrypted extension.
        if (extension.encrypt) {
          return &extension;
        }
        break;
    }
  }

  // Returning fallback extension (if any)
  return fallback_extension;
}

const RtpExtension* RtpExtension::FindHeaderExtensionByUriAndEncryption(
    const std::vector<RtpExtension>& extensions,
    absl::string_view uri,
    bool encrypt) {
  for (const auto& extension : extensions) {
    if (extension.uri == uri && extension.encrypt == encrypt) {
      return &extension;
    }
  }
  return nullptr;
}

const std::vector<RtpExtension> RtpExtension::DeduplicateHeaderExtensions(
    const std::vector<RtpExtension>& extensions,
    Filter filter) {
  std::vector<RtpExtension> filtered;

  // If we do not discard encrypted extensions, add them first
  if (filter != kDiscardEncryptedExtension) {
    for (const auto& extension : extensions) {
      if (!extension.encrypt) {
        continue;
      }
      if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
        filtered.push_back(extension);
      }
    }
  }

  // If we do not require encrypted extensions, add missing, non-encrypted
  // extensions.
  if (filter != kRequireEncryptedExtension) {
    for (const auto& extension : extensions) {
      if (extension.encrypt) {
        continue;
      }
      if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
        filtered.push_back(extension);
      }
    }
  }

  // Sort the returned vector to make comparisons of header extensions reliable.
  // In order of priority, we sort by uri first, then encrypt and id last.
  std::sort(filtered.begin(), filtered.end(),
            [](const RtpExtension& a, const RtpExtension& b) {
              return std::tie(a.uri, a.encrypt, a.id) <
                     std::tie(b.uri, b.encrypt, b.id);
            });

  return filtered;
}
}  // namespace webrtc
