/*
 *  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 <cstdint>
#include <optional>
#include <string>
#include <tuple>
#include <vector>

#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
#include "api/rtc_error.h"
#include "api/rtp_header_extension_id.h"
#include "api/rtp_transceiver_direction.h"
#include "media/base/media_constants.h"
#include "rtc_base/checks.h"
#include "rtc_base/logging.h"
#include "rtc_base/string_encode.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {
namespace {
constexpr char kSdpDelimiterSemicolon[] = ";";
constexpr char kSdpDelimiterEqualChar = '=';
constexpr char kSdpDelimiterEqual[] = "=";
constexpr char kSdpDelimiterSemicolonChar = ';';

void ParseFmtpParam(absl::string_view line,
                    std::string* parameter,
                    std::string* value) {
  if (!tokenize_first(line, kSdpDelimiterEqualChar, parameter, value)) {
    // Support for non-key-value lines like RFC 2198 or RFC 4733.
    *parameter = "";
    *value = std::string(line);
  }
  // a=fmtp:<payload_type> <param1>=<value1>; <param2>=<value2>; ...
}

bool IsFmtpParam(absl::string_view name) {
  // RFC 4855, section 3 specifies the mapping of media format parameters to SDP
  // parameters. Only ptime, maxptime, channels and rate are placed outside of
  // the fmtp line. In WebRTC, channels and rate are already handled separately
  // and thus not included in the CodecParameterMap.
  return name != kCodecParamPTime && name != kCodecParamMaxPTime;
}

void WriteFmtpParameter(absl::string_view parameter_name,
                        absl::string_view parameter_value,
                        StringBuilder& os) {
  if (parameter_name.empty()) {
    // RFC 2198 and RFC 4733 don't use key-value pairs.
    os << parameter_value;
  } else {
    // fmtp parameters: `parameter_name`=`parameter_value`
    os << parameter_name << kSdpDelimiterEqual << parameter_value;
  }
}

}  // namespace

const char* DegradationPreferenceToString(
    DegradationPreference degradation_preference) {
  switch (degradation_preference) {
    case DegradationPreference::MAINTAIN_FRAMERATE_AND_RESOLUTION:
      return "maintain-framerate-and-resolution";
    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;

bool WriteFmtpParameters(const CodecParameterMap& parameters,
                         StringBuilder& os) {
  bool empty = true;
  const char* delimiter = "";  // No delimiter before first parameter.
  for (const auto& entry : parameters) {
    const std::string& key = entry.first;
    const std::string& value = entry.second;

    if (IsFmtpParam(key)) {
      os << delimiter;
      // A semicolon before each subsequent parameter.
      delimiter = kSdpDelimiterSemicolon;
      WriteFmtpParameter(key, value, os);
      empty = false;
    }
  }

  return !empty;
}

RTCError ParseFmtpParameterSet(absl::string_view line_params,
                               CodecParameterMap& codec_params) {
  // Parse out format specific parameters.
  for (absl::string_view param :
       split(line_params, kSdpDelimiterSemicolonChar)) {
    std::string name;
    std::string value;
    ParseFmtpParam(absl::StripAsciiWhitespace(param), &name, &value);
    if (codec_params.find(name) != codec_params.end()) {
      RTC_LOG(LS_INFO) << "Overwriting duplicate fmtp parameter with key \""
                       << name << "\".";
    }
    codec_params[name] = value;
  }
  return RTCError::OK();
}

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;

RtpCodec::RtpCodec() = default;
RtpCodec::RtpCodec(const RtpCodec&) = default;
RtpCodec::~RtpCodec() = default;
bool RtpCodec::IsResiliencyCodec() const {
  return name == kRtxCodecName || name == kRedCodecName ||
         name == kUlpfecCodecName || name == kFlexfecCodecName;
}
bool RtpCodec::IsMediaCodec() const {
  return !IsResiliencyCodec() && name != kComfortNoiseCodecName;
}
RtpCodecCapability::RtpCodecCapability() = default;
RtpCodecCapability::~RtpCodecCapability() = default;

RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri)
    : uri(uri) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    RtpTransceiverDirection direction)
    : uri(uri), direction(direction) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    bool preferred_encrypt,
    RtpTransceiverDirection direction)
    : uri(uri), preferred_encrypt(preferred_encrypt), direction(direction) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    RtpHeaderExtensionId preferred_id)
    : uri(uri), preferred_id(preferred_id) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    RtpHeaderExtensionId preferred_id,
    RtpTransceiverDirection direction)
    : uri(uri),
      preferred_id(preferred_id.IsSet() ? std::optional(preferred_id)
                                        : std::nullopt),
      direction(direction) {}
RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
    absl::string_view uri,
    RtpHeaderExtensionId preferred_id,
    bool preferred_encrypt,
    RtpTransceiverDirection direction)
    : uri(uri),
      preferred_id(preferred_id.IsSet() ? std::optional(preferred_id)
                                        : std::nullopt),
      preferred_encrypt(preferred_encrypt),
      direction(direction) {}

RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;

RtpExtension::RtpExtension() = default;
RtpExtension::RtpExtension(absl::string_view uri, RtpHeaderExtensionId id)
    : uri(uri), id(id) {
  RTC_DCHECK(id.Valid()) << "Extension ID " << id << " is not in valid range";
}
RtpExtension::RtpExtension(absl::string_view uri,
                           RtpHeaderExtensionId id,
                           bool encrypt)
    : uri(uri), id(id), encrypt(encrypt) {
  RTC_DCHECK(id.Valid()) << "Extension ID " << id << " is not in valid range";
}

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 {
  StringBuilder sb;
  sb << "{uri: " << SanitizedUriForLogging();
  sb << ", id: " << id;
  if (encrypt) {
    sb << ", encrypt";
  }
  sb << "}";
  return sb.Release();
}

std::string RtpExtension::SanitizedUriForLogging() const {
  return absl::CEscape(uri);
}

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

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

bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
  return
      uri != 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 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.
  // .value() has to be used because tie compares using the <=> operator,
  // which is defined for int, but not for RtpHeaderExtensionId.
  std::sort(filtered.begin(), filtered.end(),
            [](const RtpExtension& a, const RtpExtension& b) {
              return std::tie(a.uri, a.encrypt, a.id.value()) <
                     std::tie(b.uri, b.encrypt, b.id.value());
            });

  return filtered;
}

bool RtpParameters::IsMixedCodec() const {
  std::optional<std::optional<RtpCodec>> first_codec;
  for (const RtpEncodingParameters& encoding : encodings) {
    if (!encoding.active) {
      continue;
    }
    if (!first_codec) {
      first_codec = encoding.codec;
      continue;
    }
    if (*first_codec != encoding.codec) {
      return true;
    }
  }
  return false;
}

}  // namespace webrtc
