/*
 *  Copyright (c) 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.
 */

#include "media/base/sdp_video_format_utils.h"

#include <cstring>
#include <map>
#include <optional>
#include <string>
#include <utility>

#include "api/rtp_parameters.h"
#include "api/video_codecs/h264_profile_level_id.h"
#ifdef RTC_ENABLE_H265
#include "api/video_codecs/h265_profile_tier_level.h"
#endif
#include "absl/algorithm/container.h"
#include "media/base/media_constants.h"
#include "rtc_base/checks.h"
#include "rtc_base/string_to_number.h"

namespace webrtc {
namespace {
const char kProfileLevelId[] = "profile-level-id";
const char kH264LevelAsymmetryAllowed[] = "level-asymmetry-allowed";
// Max frame rate for VP8 and VP9 video.
const char kVPxFmtpMaxFrameRate[] = "max-fr";
// Max frame size for VP8 and VP9 video.
const char kVPxFmtpMaxFrameSize[] = "max-fs";
const int kVPxFmtpFrameSizeSubBlockPixels = 256;
#ifdef RTC_ENABLE_H265
constexpr char kH265ProfileId[] = "profile-id";
constexpr char kH265TierFlag[] = "tier-flag";
constexpr char kH265LevelId[] = "level-id";
#endif

bool IsH264LevelAsymmetryAllowed(const CodecParameterMap& params) {
  const auto it = params.find(kH264LevelAsymmetryAllowed);
  return it != params.end() && strcmp(it->second.c_str(), "1") == 0;
}

// Compare H264 levels and handle the level 1b case.
bool H264LevelIsLess(H264Level a, H264Level b) {
  if (a == H264Level::kLevel1_b)
    return b != H264Level::kLevel1 && b != H264Level::kLevel1_b;
  if (b == H264Level::kLevel1_b)
    return a == H264Level::kLevel1;
  return a < b;
}

H264Level H264LevelMin(H264Level a, H264Level b) {
  return H264LevelIsLess(a, b) ? a : b;
}

std::optional<int> ParsePositiveNumberFromParams(
    const CodecParameterMap& params,
    const char* parameter_name) {
  const auto max_frame_rate_it = params.find(parameter_name);
  if (max_frame_rate_it == params.end())
    return std::nullopt;

  const std::optional<int> i = StringToNumber<int>(max_frame_rate_it->second);
  if (!i.has_value() || i.value() <= 0)
    return std::nullopt;
  return i;
}

#ifdef RTC_ENABLE_H265
// Compares two H265Level and return the smaller.
H265Level H265LevelMin(H265Level a, H265Level b) {
  return a <= b ? a : b;
}

// Returns true if none of profile-id/tier-flag/level-id is specified
// explicitly in the param.
bool IsDefaultH265PTL(const CodecParameterMap& params) {
  return !params.count(kH265ProfileId) && !params.count(kH265TierFlag) &&
         !params.count(kH265LevelId);
}
#endif

}  // namespace

#ifdef RTC_ENABLE_H265
// Set level according to https://tools.ietf.org/html/rfc7798#section-7.1
void H265GenerateProfileTierLevelForAnswer(
    const CodecParameterMap& local_supported_params,
    const CodecParameterMap& remote_offered_params,
    CodecParameterMap* answer_params) {
  // If local and remote haven't set profile-id/tier-flag/level-id, they
  // are both using the default PTL In this case, don't set PTL in answer
  // either.
  if (IsDefaultH265PTL(local_supported_params) &&
      IsDefaultH265PTL(remote_offered_params)) {
    return;
  }

  // Parse profile-tier-level.
  const std::optional<H265ProfileTierLevel> local_profile_tier_level =
      ParseSdpForH265ProfileTierLevel(local_supported_params);
  const std::optional<H265ProfileTierLevel> remote_profile_tier_level =
      ParseSdpForH265ProfileTierLevel(remote_offered_params);
  // Profile and tier for local and remote codec must be valid and equal.
  RTC_DCHECK(local_profile_tier_level);
  RTC_DCHECK(remote_profile_tier_level);
  RTC_DCHECK_EQ(local_profile_tier_level->profile,
                remote_profile_tier_level->profile);
  RTC_DCHECK_EQ(local_profile_tier_level->tier,
                remote_profile_tier_level->tier);

  const H265Level answer_level = H265LevelMin(local_profile_tier_level->level,
                                              remote_profile_tier_level->level);

  // Level-id in answer is changable as long as the highest level indicated by
  // the answer is not higher than that indicated by the offer. See
  // https://tools.ietf.org/html/rfc7798#section-7.2.2, sub-clause 2.
  (*answer_params)[kH265LevelId] = H265LevelToString(answer_level);
}
#endif

// Set level according to https://tools.ietf.org/html/rfc6184#section-8.2.2.
void H264GenerateProfileLevelIdForAnswer(
    const CodecParameterMap& local_supported_params,
    const CodecParameterMap& remote_offered_params,
    CodecParameterMap* answer_params) {
  // If both local and remote haven't set profile-level-id, they are both using
  // the default profile. In this case, don't set profile-level-id in answer
  // either.
  if (!local_supported_params.count(kProfileLevelId) &&
      !remote_offered_params.count(kProfileLevelId)) {
    return;
  }

  // Parse profile-level-ids.
  const std::optional<H264ProfileLevelId> local_profile_level_id =
      ParseSdpForH264ProfileLevelId(local_supported_params);
  const std::optional<H264ProfileLevelId> remote_profile_level_id =
      ParseSdpForH264ProfileLevelId(remote_offered_params);
  // The local and remote codec must have valid and equal H264 Profiles.
  RTC_DCHECK(local_profile_level_id);
  RTC_DCHECK(remote_profile_level_id);
  RTC_DCHECK_EQ(local_profile_level_id->profile,
                remote_profile_level_id->profile);

  // Parse level information.
  const bool level_asymmetry_allowed =
      IsH264LevelAsymmetryAllowed(local_supported_params) &&
      IsH264LevelAsymmetryAllowed(remote_offered_params);
  const H264Level local_level = local_profile_level_id->level;
  const H264Level remote_level = remote_profile_level_id->level;
  const H264Level min_level = H264LevelMin(local_level, remote_level);

  // Determine answer level. When level asymmetry is not allowed, level upgrade
  // is not allowed, i.e., the level in the answer must be equal to or lower
  // than the level in the offer.
  const H264Level answer_level =
      level_asymmetry_allowed ? local_level : min_level;

  // Set the resulting profile-level-id in the answer parameters.
  (*answer_params)[kProfileLevelId] = *H264ProfileLevelIdToString(
      H264ProfileLevelId(local_profile_level_id->profile, answer_level));
}

std::optional<int> ParseSdpForVPxMaxFrameRate(const CodecParameterMap& params) {
  return ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameRate);
}

std::optional<int> ParseSdpForVPxMaxFrameSize(const CodecParameterMap& params) {
  const std::optional<int> i =
      ParsePositiveNumberFromParams(params, kVPxFmtpMaxFrameSize);
  return i ? std::make_optional(i.value() * kVPxFmtpFrameSizeSubBlockPixels)
           : std::nullopt;
}

bool SupportsPerLayerPictureLossIndication(const CodecParameterMap& params) {
  return absl::c_find_if(
             params, [](const std::pair<std::string, std::string>& kv) {
               return kv.first == kCodecParamPerLayerPictureLossIndication &&
                      kv.second == "1";
             }) != params.end();
}

}  // namespace webrtc
