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

#ifndef RTC_BASE_EXPERIMENTS_BALANCED_DEGRADATION_SETTINGS_H_
#define RTC_BASE_EXPERIMENTS_BALANCED_DEGRADATION_SETTINGS_H_

#include <vector>

#include "absl/types/optional.h"
#include "api/field_trials_view.h"
#include "api/video_codecs/video_encoder.h"

namespace webrtc {

class BalancedDegradationSettings {
 public:
  static constexpr int kNoFpsDiff = -100;

  BalancedDegradationSettings(const FieldTrialsView& field_trials);
  ~BalancedDegradationSettings();

  struct CodecTypeSpecific {
    CodecTypeSpecific() {}
    CodecTypeSpecific(int qp_low, int qp_high, int fps, int kbps, int kbps_res)
        : qp_low(qp_low),
          qp_high(qp_high),
          fps(fps),
          kbps(kbps),
          kbps_res(kbps_res) {}

    bool operator==(const CodecTypeSpecific& o) const {
      return qp_low == o.qp_low && qp_high == o.qp_high && fps == o.fps &&
             kbps == o.kbps && kbps_res == o.kbps_res;
    }

    absl::optional<int> GetQpLow() const;
    absl::optional<int> GetQpHigh() const;
    absl::optional<int> GetFps() const;
    absl::optional<int> GetKbps() const;
    absl::optional<int> GetKbpsRes() const;

    // Optional settings.
    int qp_low = 0;
    int qp_high = 0;
    int fps = 0;       // If unset, defaults to `fps` in Config.
    int kbps = 0;      // If unset, defaults to `kbps` in Config.
    int kbps_res = 0;  // If unset, defaults to `kbps_res` in Config.
  };

  struct Config {
    Config();
    Config(int pixels,
           int fps,
           int kbps,
           int kbps_res,
           int fps_diff,
           CodecTypeSpecific vp8,
           CodecTypeSpecific vp9,
           CodecTypeSpecific h264,
           CodecTypeSpecific av1,
           CodecTypeSpecific generic);

    bool operator==(const Config& o) const {
      return pixels == o.pixels && fps == o.fps && kbps == o.kbps &&
             kbps_res == o.kbps_res && fps_diff == o.fps_diff && vp8 == o.vp8 &&
             vp9 == o.vp9 && h264 == o.h264 && av1 == o.av1 &&
             generic == o.generic;
    }

    // Example:
    // WebRTC-Video-BalancedDegradationSettings/pixels:100|200|300,fps:5|15|25/
    // pixels <= 100 -> min framerate: 5 fps
    // pixels <= 200 -> min framerate: 15 fps
    // pixels <= 300 -> min framerate: 25 fps
    //
    // WebRTC-Video-BalancedDegradationSettings/pixels:100|200|300,
    // fps:5|15|25,       // Min framerate.
    // kbps:0|60|70,      // Min bitrate needed to adapt up.
    // kbps_res:0|65|75/  // Min bitrate needed to adapt up in resolution.
    //
    // pixels: fps:  kbps:     kbps_res:
    // 300     30    -         -
    // 300     25    70 kbps   75 kbps
    // 200     25    70 kbps   -
    // 200     15    60 kbps   65 kbps
    // 100     15    60 kbps   -
    // 100      5
    //               optional  optional

    int pixels = 0;  // Video frame size.
    // If the frame size is less than or equal to `pixels`:
    int fps = 0;   // Min framerate to be used.
    int kbps = 0;  // Min bitrate needed to adapt up (resolution/fps).
    int kbps_res = 0;           // Min bitrate needed to adapt up in resolution.
    int fps_diff = kNoFpsDiff;  // Min fps reduction needed (input fps - `fps`)
                                // w/o triggering a new subsequent downgrade
                                // check.
    CodecTypeSpecific vp8;
    CodecTypeSpecific vp9;
    CodecTypeSpecific h264;
    CodecTypeSpecific av1;
    CodecTypeSpecific generic;
  };

  // Returns configurations from field trial on success (default on failure).
  std::vector<Config> GetConfigs() const;

  // Gets the min/max framerate from `configs_` based on `pixels`.
  int MinFps(VideoCodecType type, int pixels) const;
  int MaxFps(VideoCodecType type, int pixels) const;

  // Checks if quality can be increased based on `pixels` and `bitrate_bps`.
  bool CanAdaptUp(VideoCodecType type, int pixels, uint32_t bitrate_bps) const;
  bool CanAdaptUpResolution(VideoCodecType type,
                            int pixels,
                            uint32_t bitrate_bps) const;

  // Gets the min framerate diff from `configs_` based on `pixels`.
  absl::optional<int> MinFpsDiff(int pixels) const;

  // Gets QpThresholds for the codec `type` based on `pixels`.
  absl::optional<VideoEncoder::QpThresholds> GetQpThresholds(
      VideoCodecType type,
      int pixels) const;

 private:
  absl::optional<Config> GetMinFpsConfig(int pixels) const;
  absl::optional<Config> GetMaxFpsConfig(int pixels) const;
  Config GetConfig(int pixels) const;

  std::vector<Config> configs_;
};

}  // namespace webrtc

#endif  // RTC_BASE_EXPERIMENTS_BALANCED_DEGRADATION_SETTINGS_H_
