/*
 *  Copyright 2018 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 "rtc_base/experiments/quality_scaling_experiment.h"

#include <stdio.h>

#include <optional>
#include <string>

#include "absl/strings/match.h"
#include "api/field_trials_view.h"
#include "api/video/video_codec_type.h"
#include "api/video_codecs/video_encoder.h"
#include "rtc_base/checks.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace {

// This experiment controls QP thresholds for VP8, VP9, H264 and Generic codecs.
// Generic includes H265X but not standard H265.
constexpr char kFieldTrial[] = "WebRTC-Video-QualityScaling";
constexpr int kMinQp = 1;
constexpr int kMaxVp8Qp = 127;
constexpr int kMaxVp9Qp = 255;
constexpr int kMaxH264Qp = 51;
constexpr int kMaxGenericQp = 255;

#if !defined(WEBRTC_IOS)
// On non-iOS, this default string is used unless explicitly overriden.
// TODO(https://crbug.com/400338987): For use cases that does not explicitly
// turn the QP experiment on (e.g. Chrome), it does not make sense for this QP
// threshold to override the QP thresholds provided by the encoder
// implementation - we should trust that an encoder implementation that reports
// its own QP thresholds would know best, and only use these as a fallback for
// when the encoder does not specify any.
constexpr char kDefaultQualityScalingSetttings[] =
    "Enabled-29,95,149,205,24,37,26,36,0.9995,0.9999,1";
#endif

std::optional<VideoEncoder::QpThresholds> GetThresholds(int low,
                                                        int high,
                                                        int max) {
  if (low < kMinQp || high > max || high < low)
    return std::nullopt;

  RTC_LOG(LS_INFO) << "QP thresholds: low: " << low << ", high: " << high;
  return std::optional<VideoEncoder::QpThresholds>(
      VideoEncoder::QpThresholds(low, high));
}

// This experiment controls QP thresholds for standard H265 (not H265X).
// - Only for debugging/experimentation. Once QP thresholds have been determined
//   it is up to the encoder implementation to provide
//   VideoEncoder::EncoderInfo::scaling_settings.
//
// Example usage:
// --force-fieldtrials=WebRTC-H265-QualityScaling/low_qp:27,high_qp:35/
struct WebRTCH265QualityScaling {
  static constexpr char kFieldTrialName[] = "WebRTC-H265-QualityScaling";

  WebRTCH265QualityScaling(const FieldTrialsView& field_trials)
      : low_qp("low_qp"), high_qp("high_qp") {
    ParseFieldTrial({&low_qp, &high_qp}, field_trials.Lookup(kFieldTrialName));
  }

  bool IsEnabled() const { return low_qp && high_qp; }
  VideoEncoder::QpThresholds ToQpThresholds() const {
    RTC_DCHECK(IsEnabled());
    return VideoEncoder::QpThresholds(*low_qp, *high_qp);
  }

  FieldTrialOptional<int> low_qp;
  FieldTrialOptional<int> high_qp;
};
}  // namespace

bool QualityScalingExperiment::Enabled(const FieldTrialsView& field_trials) {
  WebRTCH265QualityScaling h265_quality_scaling(field_trials);
  return
#if defined(WEBRTC_IOS)
      absl::StartsWith(field_trials.Lookup(kFieldTrial), "Enabled") ||
#else
      !absl::StartsWith(field_trials.Lookup(kFieldTrial), "Disabled") ||
#endif
      h265_quality_scaling.IsEnabled();
}

std::optional<QualityScalingExperiment::Settings>
QualityScalingExperiment::ParseSettings(const FieldTrialsView& field_trials) {
  std::string group = field_trials.Lookup(kFieldTrial);
  // TODO(http://crbug.com/webrtc/12401): Completely remove the experiment code
  // after few releases.
#if !defined(WEBRTC_IOS)
  if (group.empty())
    group = kDefaultQualityScalingSetttings;
#endif
  Settings s;
  if (sscanf(group.c_str(), "Enabled-%d,%d,%d,%d,%d,%d,%d,%d,%f,%f,%d",
             &s.vp8_low, &s.vp8_high, &s.vp9_low, &s.vp9_high, &s.h264_low,
             &s.h264_high, &s.generic_low, &s.generic_high, &s.alpha_high,
             &s.alpha_low, &s.drop) != 11) {
    RTC_LOG(LS_WARNING) << "Invalid number of parameters provided.";
    return std::nullopt;
  }
  return s;
}

std::optional<VideoEncoder::QpThresholds>
QualityScalingExperiment::GetQpThresholds(VideoCodecType codec_type,
                                          const FieldTrialsView& field_trials) {
  if (codec_type == kVideoCodecH265) {
    WebRTCH265QualityScaling h265_quality_scaling(field_trials);
    if (h265_quality_scaling.IsEnabled()) {
      return h265_quality_scaling.ToQpThresholds();
    }
  }
  const auto settings = ParseSettings(field_trials);
  if (!settings)
    return std::nullopt;

  switch (codec_type) {
    case kVideoCodecVP8:
      return GetThresholds(settings->vp8_low, settings->vp8_high, kMaxVp8Qp);
    case kVideoCodecVP9:
      return GetThresholds(settings->vp9_low, settings->vp9_high, kMaxVp9Qp);
    case kVideoCodecH264:
      return GetThresholds(settings->h264_low, settings->h264_high, kMaxH264Qp);
    case kVideoCodecGeneric:
      return GetThresholds(settings->generic_low, settings->generic_high,
                           kMaxGenericQp);
    default:
      return std::nullopt;
  }
}

QualityScalingExperiment::Config QualityScalingExperiment::GetConfig(
    const FieldTrialsView& field_trials) {
  const auto settings = ParseSettings(field_trials);
  if (!settings)
    return Config();

  Config config;
  config.use_all_drop_reasons = settings->drop > 0;

  if (settings->alpha_high < 0 || settings->alpha_low < settings->alpha_high) {
    RTC_LOG(LS_WARNING) << "Invalid alpha value provided, using default.";
    return config;
  }
  config.alpha_high = settings->alpha_high;
  config.alpha_low = settings->alpha_low;
  return config;
}

}  // namespace webrtc
