/*
 *  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 "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)
      field_trials.IsEnabled(kFieldTrial) ||
#else
      !field_trials.IsDisabled(kFieldTrial) ||
#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
