/*
 *  Copyright (c) 2004 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 "media/base/codec.h"

#include "absl/algorithm/container.h"
#include "absl/strings/match.h"
#include "api/video_codecs/av1_profile.h"
#include "api/video_codecs/h264_profile_level_id.h"
#include "api/video_codecs/vp9_profile.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 cricket {
namespace {

std::string GetH264PacketizationModeOrDefault(const CodecParameterMap& params) {
  auto it = params.find(kH264FmtpPacketizationMode);
  if (it != params.end()) {
    return it->second;
  }
  // If packetization-mode is not present, default to "0".
  // https://tools.ietf.org/html/rfc6184#section-6.2
  return "0";
}

bool IsSameH264PacketizationMode(const CodecParameterMap& left,
                                 const CodecParameterMap& right) {
  return GetH264PacketizationModeOrDefault(left) ==
         GetH264PacketizationModeOrDefault(right);
}

// Some (video) codecs are actually families of codecs and rely on parameters
// to distinguish different incompatible family members.
bool IsSameCodecSpecific(const std::string& name1,
                         const CodecParameterMap& params1,
                         const std::string& name2,
                         const CodecParameterMap& params2) {
  // The names might not necessarily match, so check both.
  auto either_name_matches = [&](const std::string name) {
    return absl::EqualsIgnoreCase(name, name1) ||
           absl::EqualsIgnoreCase(name, name2);
  };
  if (either_name_matches(kH264CodecName))
    return webrtc::H264IsSameProfile(params1, params2) &&
           IsSameH264PacketizationMode(params1, params2);
  if (either_name_matches(kVp9CodecName))
    return webrtc::VP9IsSameProfile(params1, params2);
  if (either_name_matches(kAv1CodecName))
    return webrtc::AV1IsSameProfile(params1, params2);
  return true;
}

}  // namespace

FeedbackParams::FeedbackParams() = default;
FeedbackParams::~FeedbackParams() = default;

bool FeedbackParam::operator==(const FeedbackParam& other) const {
  return absl::EqualsIgnoreCase(other.id(), id()) &&
         absl::EqualsIgnoreCase(other.param(), param());
}

bool FeedbackParams::operator==(const FeedbackParams& other) const {
  return params_ == other.params_;
}

bool FeedbackParams::Has(const FeedbackParam& param) const {
  return absl::c_linear_search(params_, param);
}

void FeedbackParams::Add(const FeedbackParam& param) {
  if (param.id().empty()) {
    return;
  }
  if (Has(param)) {
    // Param already in `this`.
    return;
  }
  params_.push_back(param);
  RTC_CHECK(!HasDuplicateEntries());
}

void FeedbackParams::Intersect(const FeedbackParams& from) {
  std::vector<FeedbackParam>::iterator iter_to = params_.begin();
  while (iter_to != params_.end()) {
    if (!from.Has(*iter_to)) {
      iter_to = params_.erase(iter_to);
    } else {
      ++iter_to;
    }
  }
}

bool FeedbackParams::HasDuplicateEntries() const {
  for (std::vector<FeedbackParam>::const_iterator iter = params_.begin();
       iter != params_.end(); ++iter) {
    for (std::vector<FeedbackParam>::const_iterator found = iter + 1;
         found != params_.end(); ++found) {
      if (*found == *iter) {
        return true;
      }
    }
  }
  return false;
}

Codec::Codec(Type type, int id, const std::string& name, int clockrate)
    : Codec(type, id, name, clockrate, 0) {}
Codec::Codec(Type type,
             int id,
             const std::string& name,
             int clockrate,
             size_t channels)
    : type(type),
      id(id),
      name(name),
      clockrate(clockrate),
      bitrate(0),
      channels(channels) {}

Codec::Codec(Type type) : Codec(type, 0, "", 0) {}

Codec::Codec(const webrtc::SdpVideoFormat& c)
    : Codec(Type::kVideo, 0, c.name, kVideoCodecClockrate) {
  params = c.parameters;
  scalability_modes = c.scalability_modes;
}

Codec::Codec(const Codec& c) = default;
Codec::Codec(Codec&& c) = default;
Codec::~Codec() = default;
Codec& Codec::operator=(const Codec& c) = default;
Codec& Codec::operator=(Codec&& c) = default;

bool Codec::operator==(const Codec& c) const {
  return type == c.type && this->id == c.id &&  // id is reserved in objective-c
         name == c.name && clockrate == c.clockrate && params == c.params &&
         feedback_params == c.feedback_params &&
         (type == Type::kAudio
              ? (bitrate == c.bitrate && channels == c.channels)
              : (packetization == c.packetization));
}

bool Codec::Matches(const Codec& codec,
                    const webrtc::FieldTrialsView* field_trials) const {
  // Match the codec id/name based on the typical static/dynamic name rules.
  // Matching is case-insensitive.

  // We support the ranges [96, 127] and more recently [35, 65].
  // https://www.iana.org/assignments/rtp-parameters/rtp-parameters.xhtml#rtp-parameters-1
  // Within those ranges we match by codec name, outside by codec id.
  // Since no codecs are assigned an id in the range [66, 95] by us, these will
  // never match.
  const int kLowerDynamicRangeMin = 35;
  const int kLowerDynamicRangeMax = 65;
  const int kUpperDynamicRangeMin = 96;
  const int kUpperDynamicRangeMax = 127;
  const bool is_id_in_dynamic_range =
      (id >= kLowerDynamicRangeMin && id <= kLowerDynamicRangeMax) ||
      (id >= kUpperDynamicRangeMin && id <= kUpperDynamicRangeMax);
  const bool is_codec_id_in_dynamic_range =
      (codec.id >= kLowerDynamicRangeMin &&
       codec.id <= kLowerDynamicRangeMax) ||
      (codec.id >= kUpperDynamicRangeMin && codec.id <= kUpperDynamicRangeMax);
  bool matches_id = is_id_in_dynamic_range && is_codec_id_in_dynamic_range
                        ? (absl::EqualsIgnoreCase(name, codec.name))
                        : (id == codec.id);

  auto matches_type_specific = [&]() {
    switch (type) {
      case Type::kAudio:
        // If a nonzero clockrate is specified, it must match the actual
        // clockrate. If a nonzero bitrate is specified, it must match the
        // actual bitrate, unless the codec is VBR (0), where we just force the
        // supplied value. The number of channels must match exactly, with the
        // exception that channels=0 is treated synonymously as channels=1, per
        // RFC 4566 section 6: " [The channels] parameter is OPTIONAL and may be
        // omitted if the number of channels is one."
        // Preference is ignored.
        // TODO(juberti): Treat a zero clockrate as 8000Hz, the RTP default
        // clockrate.
        return ((codec.clockrate == 0 /*&& clockrate == 8000*/) ||
                clockrate == codec.clockrate) &&
               (codec.bitrate == 0 || bitrate <= 0 ||
                bitrate == codec.bitrate) &&
               ((codec.channels < 2 && channels < 2) ||
                channels == codec.channels);

      case Type::kVideo:
        return IsSameCodecSpecific(name, params, codec.name, codec.params);
    }
  };

  return matches_id && matches_type_specific();
}

bool Codec::MatchesCapability(
    const webrtc::RtpCodecCapability& codec_capability) const {
  webrtc::RtpCodecParameters codec_parameters = ToCodecParameters();

  return codec_parameters.name == codec_capability.name &&
         codec_parameters.kind == codec_capability.kind &&
         (codec_parameters.name == cricket::kRtxCodecName ||
          (codec_parameters.num_channels == codec_capability.num_channels &&
           codec_parameters.clock_rate == codec_capability.clock_rate &&
           codec_parameters.parameters == codec_capability.parameters));
}

bool Codec::GetParam(const std::string& name, std::string* out) const {
  CodecParameterMap::const_iterator iter = params.find(name);
  if (iter == params.end())
    return false;
  *out = iter->second;
  return true;
}

bool Codec::GetParam(const std::string& name, int* out) const {
  CodecParameterMap::const_iterator iter = params.find(name);
  if (iter == params.end())
    return false;
  return rtc::FromString(iter->second, out);
}

void Codec::SetParam(const std::string& name, const std::string& value) {
  params[name] = value;
}

void Codec::SetParam(const std::string& name, int value) {
  params[name] = rtc::ToString(value);
}

bool Codec::RemoveParam(const std::string& name) {
  return params.erase(name) == 1;
}

void Codec::AddFeedbackParam(const FeedbackParam& param) {
  feedback_params.Add(param);
}

bool Codec::HasFeedbackParam(const FeedbackParam& param) const {
  return feedback_params.Has(param);
}

void Codec::IntersectFeedbackParams(const Codec& other) {
  feedback_params.Intersect(other.feedback_params);
}

webrtc::RtpCodecParameters Codec::ToCodecParameters() const {
  webrtc::RtpCodecParameters codec_params;
  codec_params.payload_type = id;
  codec_params.name = name;
  codec_params.clock_rate = clockrate;
  codec_params.parameters.insert(params.begin(), params.end());

  switch (type) {
    case Type::kAudio: {
      codec_params.num_channels = static_cast<int>(channels);
      codec_params.kind = MEDIA_TYPE_AUDIO;
      break;
    }
    case Type::kVideo: {
      codec_params.kind = MEDIA_TYPE_VIDEO;
      break;
    }
  }

  return codec_params;
}

bool Codec::IsMediaCodec() const {
  return !IsResiliencyCodec();
}

bool Codec::IsResiliencyCodec() const {
  return GetResiliencyType() != ResiliencyType::kNone;
}

Codec::ResiliencyType Codec::GetResiliencyType() const {
  if (absl::EqualsIgnoreCase(name, kRedCodecName)) {
    return ResiliencyType::kRed;
  }
  if (absl::EqualsIgnoreCase(name, kUlpfecCodecName)) {
    return ResiliencyType::kUlpfec;
  }
  if (absl::EqualsIgnoreCase(name, kFlexfecCodecName)) {
    return ResiliencyType::kFlexfec;
  }
  if (absl::EqualsIgnoreCase(name, kRtxCodecName)) {
    return ResiliencyType::kRtx;
  }
  return ResiliencyType::kNone;
}

bool Codec::ValidateCodecFormat() const {
  if (id < 0 || id > 127) {
    RTC_LOG(LS_ERROR) << "Codec with invalid payload type: " << ToString();
    return false;
  }
  if (IsResiliencyCodec()) {
    return true;
  }

  int min_bitrate = -1;
  int max_bitrate = -1;
  if (GetParam(kCodecParamMinBitrate, &min_bitrate) &&
      GetParam(kCodecParamMaxBitrate, &max_bitrate)) {
    if (max_bitrate < min_bitrate) {
      RTC_LOG(LS_ERROR) << "Codec with max < min bitrate: " << ToString();
      return false;
    }
  }
  return true;
}

AudioCodec::AudioCodec(int id,
                       const std::string& name,
                       int clockrate,
                       int unused_bitrate,
                       size_t channels)
    : Codec(Type::kAudio, id, name, clockrate, channels) {}

AudioCodec::AudioCodec() : Codec(Type::kAudio) {}

AudioCodec::AudioCodec(const AudioCodec& c) = default;
AudioCodec::AudioCodec(AudioCodec&& c) = default;
AudioCodec& AudioCodec::operator=(const AudioCodec& c) = default;
AudioCodec& AudioCodec::operator=(AudioCodec&& c) = default;

std::string Codec::ToString() const {
  char buf[256];

  rtc::SimpleStringBuilder sb(buf);
  switch (type) {
    case Type::kAudio: {
      sb << "AudioCodec[" << id << ":" << name << ":" << clockrate << ":"
         << bitrate << ":" << channels << "]";
      break;
    }
    case Type::kVideo: {
      sb << "VideoCodec[" << id << ":" << name;
      if (packetization.has_value()) {
        sb << ":" << *packetization;
      }
      sb << "]";
      break;
    }
  }
  return sb.str();
}

VideoCodec::VideoCodec(int id, const std::string& name)
    : Codec(Type::kVideo, id, name, kVideoCodecClockrate) {
  SetDefaultParameters();
}

VideoCodec::VideoCodec(const std::string& name) : VideoCodec(0 /* id */, name) {
  SetDefaultParameters();
}

VideoCodec::VideoCodec() : Codec(Type::kVideo) {
  clockrate = kVideoCodecClockrate;
}

VideoCodec::VideoCodec(const webrtc::SdpVideoFormat& c) : Codec(c) {}

VideoCodec::VideoCodec(const VideoCodec& c) = default;
VideoCodec::VideoCodec(VideoCodec&& c) = default;
VideoCodec& VideoCodec::operator=(const VideoCodec& c) = default;
VideoCodec& VideoCodec::operator=(VideoCodec&& c) = default;

void VideoCodec::SetDefaultParameters() {
  if (absl::EqualsIgnoreCase(kH264CodecName, name)) {
    // This default is set for all H.264 codecs created because
    // that was the default before packetization mode support was added.
    // TODO(hta): Move this to the places that create VideoCodecs from
    // SDP or from knowledge of implementation capabilities.
    SetParam(kH264FmtpPacketizationMode, "1");
  }
}

VideoCodec VideoCodec::CreateRtxCodec(int rtx_payload_type,
                                      int associated_payload_type) {
  return CreateVideoRtxCodec(rtx_payload_type, associated_payload_type);
}

VideoCodec CreateVideoRtxCodec(int rtx_payload_type,
                               int associated_payload_type) {
  VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName);
  rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type);
  return rtx_codec;
}

VideoCodec::CodecType VideoCodec::GetCodecType() const {
  if (absl::EqualsIgnoreCase(name, kRedCodecName)) {
    return CODEC_RED;
  }
  if (absl::EqualsIgnoreCase(name, kUlpfecCodecName)) {
    return CODEC_ULPFEC;
  }
  if (absl::EqualsIgnoreCase(name, kFlexfecCodecName)) {
    return CODEC_FLEXFEC;
  }
  if (absl::EqualsIgnoreCase(name, kRtxCodecName)) {
    return CODEC_RTX;
  }

  return CODEC_VIDEO;
}

bool HasLntf(const Codec& codec) {
  return codec.HasFeedbackParam(
      FeedbackParam(kRtcpFbParamLntf, kParamValueEmpty));
}

bool HasNack(const Codec& codec) {
  return codec.HasFeedbackParam(
      FeedbackParam(kRtcpFbParamNack, kParamValueEmpty));
}

bool HasRemb(const Codec& codec) {
  return codec.HasFeedbackParam(
      FeedbackParam(kRtcpFbParamRemb, kParamValueEmpty));
}

bool HasRrtr(const Codec& codec) {
  return codec.HasFeedbackParam(
      FeedbackParam(kRtcpFbParamRrtr, kParamValueEmpty));
}

bool HasTransportCc(const Codec& codec) {
  return codec.HasFeedbackParam(
      FeedbackParam(kRtcpFbParamTransportCc, kParamValueEmpty));
}

const VideoCodec* FindMatchingCodec(
    const std::vector<VideoCodec>& supported_codecs,
    const VideoCodec& codec) {
  webrtc::SdpVideoFormat sdp_video_format{codec.name, codec.params};
  for (const VideoCodec& supported_codec : supported_codecs) {
    if (sdp_video_format.IsSameCodec(
            {supported_codec.name, supported_codec.params})) {
      return &supported_codec;
    }
  }
  return nullptr;
}

// If a decoder supports any H264 profile, it is implicitly assumed to also
// support constrained base line even though it's not explicitly listed.
void AddH264ConstrainedBaselineProfileToSupportedFormats(
    std::vector<webrtc::SdpVideoFormat>* supported_formats) {
  std::vector<webrtc::SdpVideoFormat> cbr_supported_formats;

  // For any H264 supported profile, add the corresponding constrained baseline
  // profile.
  for (auto it = supported_formats->cbegin(); it != supported_formats->cend();
       ++it) {
    if (it->name == cricket::kH264CodecName) {
      const absl::optional<webrtc::H264ProfileLevelId> profile_level_id =
          webrtc::ParseSdpForH264ProfileLevelId(it->parameters);
      if (profile_level_id &&
          profile_level_id->profile !=
              webrtc::H264Profile::kProfileConstrainedBaseline) {
        webrtc::SdpVideoFormat cbp_format = *it;
        webrtc::H264ProfileLevelId cbp_profile = *profile_level_id;
        cbp_profile.profile = webrtc::H264Profile::kProfileConstrainedBaseline;
        cbp_format.parameters[cricket::kH264FmtpProfileLevelId] =
            *webrtc::H264ProfileLevelIdToString(cbp_profile);
        cbr_supported_formats.push_back(cbp_format);
      }
    }
  }

  size_t original_size = supported_formats->size();
  // ...if it's not already in the list.
  std::copy_if(cbr_supported_formats.begin(), cbr_supported_formats.end(),
               std::back_inserter(*supported_formats),
               [supported_formats](const webrtc::SdpVideoFormat& format) {
                 return !format.IsCodecInList(*supported_formats);
               });

  if (supported_formats->size() > original_size) {
    RTC_LOG(LS_WARNING) << "Explicitly added H264 constrained baseline to list "
                           "of supported formats.";
  }
}

AudioCodec CreateAudioCodec(int id,
                            const std::string& name,
                            int clockrate,
                            size_t channels) {
  return AudioCodec(id, name, clockrate, 0, channels);
}

VideoCodec CreateVideoCodec(const std::string& name) {
  return VideoCodec(name);
}

VideoCodec CreateVideoCodec(int id, const std::string& name) {
  return VideoCodec(id, name);
}

}  // namespace cricket
