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

#include "rtc_base/experiments/balanced_degradation_settings.h"

#include <cstddef>
#include <cstdint>
#include <limits>
#include <optional>
#include <vector>

#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_list.h"
#include "rtc_base/experiments/field_trial_parser.h"
#include "rtc_base/logging.h"

namespace webrtc {
namespace {
constexpr char kFieldTrial[] = "WebRTC-Video-BalancedDegradationSettings";
constexpr int kMinFps = 1;
constexpr int kMaxFps = 100;  // 100 means unlimited fps.

std::vector<BalancedDegradationSettings::Config> DefaultConfigs() {
  return {{320 * 240,
           7,
           0,
           0,
           BalancedDegradationSettings::kNoFpsDiff,
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0}},
          {480 * 360,
           10,
           0,
           0,
           1,
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0}},
          {640 * 480,
           15,
           0,
           0,
           1,
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0},
           {0, 0, 0, 0, 0}}};
}

bool IsValidConfig(
    const BalancedDegradationSettings::CodecTypeSpecific& config) {
  if (config.GetQpLow().has_value() != config.GetQpHigh().has_value()) {
    RTC_LOG(LS_WARNING) << "Neither or both thresholds should be set.";
    return false;
  }
  if (config.GetQpLow().has_value() && config.GetQpHigh().has_value() &&
      config.GetQpLow().value() >= config.GetQpHigh().value()) {
    RTC_LOG(LS_WARNING) << "Invalid threshold value, low >= high threshold.";
    return false;
  }
  if (config.GetFps().has_value() && (config.GetFps().value() < kMinFps ||
                                      config.GetFps().value() > kMaxFps)) {
    RTC_LOG(LS_WARNING) << "Unsupported fps setting, value ignored.";
    return false;
  }
  return true;
}

bool IsValid(const BalancedDegradationSettings::CodecTypeSpecific& config1,
             const BalancedDegradationSettings::CodecTypeSpecific& config2) {
  bool both_or_none_set = ((config1.qp_low > 0) == (config2.qp_low > 0) &&
                           (config1.qp_high > 0) == (config2.qp_high > 0) &&
                           (config1.fps > 0) == (config2.fps > 0));
  if (!both_or_none_set) {
    RTC_LOG(LS_WARNING) << "Invalid value, all/none should be set.";
    return false;
  }
  if (config1.fps > 0 && config1.fps < config2.fps) {
    RTC_LOG(LS_WARNING) << "Invalid fps/pixel value provided.";
    return false;
  }
  return true;
}

bool IsValid(const std::vector<BalancedDegradationSettings::Config>& configs) {
  if (configs.size() <= 1) {
    if (configs.size() == 1)
      RTC_LOG(LS_WARNING) << "Unsupported size, value ignored.";
    return false;
  }
  for (const auto& config : configs) {
    if (config.fps < kMinFps || config.fps > kMaxFps) {
      RTC_LOG(LS_WARNING) << "Unsupported fps setting, value ignored.";
      return false;
    }
  }
  int last_kbps = configs[0].kbps;
  for (size_t i = 1; i < configs.size(); ++i) {
    if (configs[i].kbps > 0) {
      if (configs[i].kbps < last_kbps) {
        RTC_LOG(LS_WARNING) << "Invalid bitrate value provided.";
        return false;
      }
      last_kbps = configs[i].kbps;
    }
  }
  for (size_t i = 1; i < configs.size(); ++i) {
    if (configs[i].pixels < configs[i - 1].pixels ||
        configs[i].fps < configs[i - 1].fps) {
      RTC_LOG(LS_WARNING) << "Invalid fps/pixel value provided.";
      return false;
    }
    if (!IsValid(configs[i].vp8, configs[i - 1].vp8) ||
        !IsValid(configs[i].vp9, configs[i - 1].vp9) ||
        !IsValid(configs[i].h264, configs[i - 1].h264) ||
        !IsValid(configs[i].av1, configs[i - 1].av1) ||
        !IsValid(configs[i].generic, configs[i - 1].generic)) {
      return false;
    }
  }
  for (const auto& config : configs) {
    if (!IsValidConfig(config.vp8) || !IsValidConfig(config.vp9) ||
        !IsValidConfig(config.h264) || !IsValidConfig(config.av1) ||
        !IsValidConfig(config.generic)) {
      return false;
    }
  }
  return true;
}

std::vector<BalancedDegradationSettings::Config> GetValidOrDefault(
    const std::vector<BalancedDegradationSettings::Config>& configs) {
  if (IsValid(configs)) {
    return configs;
  }
  return DefaultConfigs();
}

std::optional<VideoEncoder::QpThresholds> GetThresholds(
    VideoCodecType type,
    const BalancedDegradationSettings::Config& config) {
  std::optional<int> low;
  std::optional<int> high;

  switch (type) {
    case kVideoCodecVP8:
      low = config.vp8.GetQpLow();
      high = config.vp8.GetQpHigh();
      break;
    case kVideoCodecVP9:
      low = config.vp9.GetQpLow();
      high = config.vp9.GetQpHigh();
      break;
    case kVideoCodecH265:
    //  TODO(bugs.webrtc.org/13485): Use H264 QP thresholds for now.
    case kVideoCodecH264:
      low = config.h264.GetQpLow();
      high = config.h264.GetQpHigh();
      break;
    case kVideoCodecAV1:
      low = config.av1.GetQpLow();
      high = config.av1.GetQpHigh();
      break;
    case kVideoCodecGeneric:
      low = config.generic.GetQpLow();
      high = config.generic.GetQpHigh();
      break;
    default:
      break;
  }

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

int GetFps(VideoCodecType type,
           const std::optional<BalancedDegradationSettings::Config>& config) {
  if (!config.has_value()) {
    return std::numeric_limits<int>::max();
  }

  std::optional<int> fps;
  switch (type) {
    case kVideoCodecVP8:
      fps = config->vp8.GetFps();
      break;
    case kVideoCodecH265:
    //  TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
    case kVideoCodecVP9:
      fps = config->vp9.GetFps();
      break;
    case kVideoCodecH264:
      fps = config->h264.GetFps();
      break;
    case kVideoCodecAV1:
      fps = config->av1.GetFps();
      break;
    case kVideoCodecGeneric:
      fps = config->generic.GetFps();
      break;
    default:
      break;
  }

  const int framerate = fps.value_or(config->fps);

  return (framerate == kMaxFps) ? std::numeric_limits<int>::max() : framerate;
}

std::optional<int> GetKbps(
    VideoCodecType type,
    const std::optional<BalancedDegradationSettings::Config>& config) {
  if (!config.has_value())
    return std::nullopt;

  std::optional<int> kbps;
  switch (type) {
    case kVideoCodecVP8:
      kbps = config->vp8.GetKbps();
      break;
    case kVideoCodecH265:
    //  TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
    case kVideoCodecVP9:
      kbps = config->vp9.GetKbps();
      break;
    case kVideoCodecH264:
      kbps = config->h264.GetKbps();
      break;
    case kVideoCodecAV1:
      kbps = config->av1.GetKbps();
      break;
    case kVideoCodecGeneric:
      kbps = config->generic.GetKbps();
      break;
    default:
      break;
  }

  if (kbps.has_value())
    return kbps;

  return config->kbps > 0 ? std::optional<int>(config->kbps) : std::nullopt;
}

std::optional<int> GetKbpsRes(
    VideoCodecType type,
    const std::optional<BalancedDegradationSettings::Config>& config) {
  if (!config.has_value())
    return std::nullopt;

  std::optional<int> kbps_res;
  switch (type) {
    case kVideoCodecVP8:
      kbps_res = config->vp8.GetKbpsRes();
      break;
    case kVideoCodecH265:
    //  TODO(bugs.webrtc.org/13485): Use VP9 bitrate limits for now.
    case kVideoCodecVP9:
      kbps_res = config->vp9.GetKbpsRes();
      break;
    case kVideoCodecH264:
      kbps_res = config->h264.GetKbpsRes();
      break;
    case kVideoCodecAV1:
      kbps_res = config->av1.GetKbpsRes();
      break;
    case kVideoCodecGeneric:
      kbps_res = config->generic.GetKbpsRes();
      break;
    default:
      break;
  }

  if (kbps_res.has_value())
    return kbps_res;

  return config->kbps_res > 0 ? std::optional<int>(config->kbps_res)
                              : std::nullopt;
}
}  // namespace

std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpLow()
    const {
  return (qp_low > 0) ? std::optional<int>(qp_low) : std::nullopt;
}

std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetQpHigh()
    const {
  return (qp_high > 0) ? std::optional<int>(qp_high) : std::nullopt;
}

std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetFps()
    const {
  return (fps > 0) ? std::optional<int>(fps) : std::nullopt;
}

std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbps()
    const {
  return (kbps > 0) ? std::optional<int>(kbps) : std::nullopt;
}

std::optional<int> BalancedDegradationSettings::CodecTypeSpecific::GetKbpsRes()
    const {
  return (kbps_res > 0) ? std::optional<int>(kbps_res) : std::nullopt;
}

BalancedDegradationSettings::Config::Config() = default;

BalancedDegradationSettings::Config::Config(int pixels,
                                            int fps,
                                            int kbps,
                                            int kbps_res,
                                            int fps_diff,
                                            CodecTypeSpecific vp8,
                                            CodecTypeSpecific vp9,
                                            CodecTypeSpecific h264,
                                            CodecTypeSpecific av1,
                                            CodecTypeSpecific generic)
    : pixels(pixels),
      fps(fps),
      kbps(kbps),
      kbps_res(kbps_res),
      fps_diff(fps_diff),
      vp8(vp8),
      vp9(vp9),
      h264(h264),
      av1(av1),
      generic(generic) {}

BalancedDegradationSettings::BalancedDegradationSettings(
    const FieldTrialsView& field_trials) {
  FieldTrialStructList<Config> configs(
      {FieldTrialStructMember("pixels", [](Config* c) { return &c->pixels; }),
       FieldTrialStructMember("fps", [](Config* c) { return &c->fps; }),
       FieldTrialStructMember("kbps", [](Config* c) { return &c->kbps; }),
       FieldTrialStructMember("kbps_res",
                              [](Config* c) { return &c->kbps_res; }),
       FieldTrialStructMember("fps_diff",
                              [](Config* c) { return &c->fps_diff; }),
       FieldTrialStructMember("vp8_qp_low",
                              [](Config* c) { return &c->vp8.qp_low; }),
       FieldTrialStructMember("vp8_qp_high",
                              [](Config* c) { return &c->vp8.qp_high; }),
       FieldTrialStructMember("vp8_fps", [](Config* c) { return &c->vp8.fps; }),
       FieldTrialStructMember("vp8_kbps",
                              [](Config* c) { return &c->vp8.kbps; }),
       FieldTrialStructMember("vp8_kbps_res",
                              [](Config* c) { return &c->vp8.kbps_res; }),
       FieldTrialStructMember("vp9_qp_low",
                              [](Config* c) { return &c->vp9.qp_low; }),
       FieldTrialStructMember("vp9_qp_high",
                              [](Config* c) { return &c->vp9.qp_high; }),
       FieldTrialStructMember("vp9_fps", [](Config* c) { return &c->vp9.fps; }),
       FieldTrialStructMember("vp9_kbps",
                              [](Config* c) { return &c->vp9.kbps; }),
       FieldTrialStructMember("vp9_kbps_res",
                              [](Config* c) { return &c->vp9.kbps_res; }),
       FieldTrialStructMember("h264_qp_low",
                              [](Config* c) { return &c->h264.qp_low; }),
       FieldTrialStructMember("h264_qp_high",
                              [](Config* c) { return &c->h264.qp_high; }),
       FieldTrialStructMember("h264_fps",
                              [](Config* c) { return &c->h264.fps; }),
       FieldTrialStructMember("h264_kbps",
                              [](Config* c) { return &c->h264.kbps; }),
       FieldTrialStructMember("h264_kbps_res",
                              [](Config* c) { return &c->h264.kbps_res; }),
       FieldTrialStructMember("av1_qp_low",
                              [](Config* c) { return &c->av1.qp_low; }),
       FieldTrialStructMember("av1_qp_high",
                              [](Config* c) { return &c->av1.qp_high; }),
       FieldTrialStructMember("av1_fps", [](Config* c) { return &c->av1.fps; }),
       FieldTrialStructMember("av1_kbps",
                              [](Config* c) { return &c->av1.kbps; }),
       FieldTrialStructMember("av1_kbps_res",
                              [](Config* c) { return &c->av1.kbps_res; }),
       FieldTrialStructMember("generic_qp_low",
                              [](Config* c) { return &c->generic.qp_low; }),
       FieldTrialStructMember("generic_qp_high",
                              [](Config* c) { return &c->generic.qp_high; }),
       FieldTrialStructMember("generic_fps",
                              [](Config* c) { return &c->generic.fps; }),
       FieldTrialStructMember("generic_kbps",
                              [](Config* c) { return &c->generic.kbps; }),
       FieldTrialStructMember("generic_kbps_res",
                              [](Config* c) { return &c->generic.kbps_res; })},
      {});

  ParseFieldTrial({&configs}, field_trials.Lookup(kFieldTrial));

  configs_ = GetValidOrDefault(configs.Get());
  RTC_DCHECK_GT(configs_.size(), 1);
}

BalancedDegradationSettings::~BalancedDegradationSettings() {}

std::vector<BalancedDegradationSettings::Config>
BalancedDegradationSettings::GetConfigs() const {
  return configs_;
}

int BalancedDegradationSettings::MinFps(VideoCodecType type, int pixels) const {
  return GetFps(type, GetMinFpsConfig(pixels));
}

std::optional<BalancedDegradationSettings::Config>
BalancedDegradationSettings::GetMinFpsConfig(int pixels) const {
  for (const auto& config : configs_) {
    if (pixels <= config.pixels)
      return config;
  }
  return std::nullopt;
}

int BalancedDegradationSettings::MaxFps(VideoCodecType type, int pixels) const {
  return GetFps(type, GetMaxFpsConfig(pixels));
}

std::optional<BalancedDegradationSettings::Config>
BalancedDegradationSettings::GetMaxFpsConfig(int pixels) const {
  for (size_t i = 0; i < configs_.size() - 1; ++i) {
    if (pixels <= configs_[i].pixels)
      return configs_[i + 1];
  }
  return std::nullopt;
}

bool BalancedDegradationSettings::CanAdaptUp(VideoCodecType type,
                                             int pixels,
                                             uint32_t bitrate_bps) const {
  std::optional<int> min_kbps = GetKbps(type, GetMaxFpsConfig(pixels));
  if (!min_kbps.has_value() || bitrate_bps == 0) {
    return true;  // No limit configured or bitrate provided.
  }
  return bitrate_bps >= static_cast<uint32_t>(min_kbps.value() * 1000);
}

bool BalancedDegradationSettings::CanAdaptUpResolution(
    VideoCodecType type,
    int pixels,
    uint32_t bitrate_bps) const {
  std::optional<int> min_kbps = GetKbpsRes(type, GetMaxFpsConfig(pixels));
  if (!min_kbps.has_value() || bitrate_bps == 0) {
    return true;  // No limit configured or bitrate provided.
  }
  return bitrate_bps >= static_cast<uint32_t>(min_kbps.value() * 1000);
}

std::optional<int> BalancedDegradationSettings::MinFpsDiff(int pixels) const {
  for (const auto& config : configs_) {
    if (pixels <= config.pixels) {
      return (config.fps_diff > kNoFpsDiff)
                 ? std::optional<int>(config.fps_diff)
                 : std::nullopt;
    }
  }
  return std::nullopt;
}

std::optional<VideoEncoder::QpThresholds>
BalancedDegradationSettings::GetQpThresholds(VideoCodecType type,
                                             int pixels) const {
  return GetThresholds(type, GetConfig(pixels));
}

BalancedDegradationSettings::Config BalancedDegradationSettings::GetConfig(
    int pixels) const {
  for (const auto& config : configs_) {
    if (pixels <= config.pixels)
      return config;
  }
  return configs_.back();  // Use last above highest pixels.
}

}  // namespace webrtc
