/*
 *  Copyright (c) 2014 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 "video/config/video_encoder_config.h"

#include <cstddef>
#include <optional>
#include <string>

#include "api/video/video_codec_type.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_codec.h"
#include "rtc_base/checks.h"
#include "rtc_base/strings/string_builder.h"

namespace webrtc {
VideoStream::VideoStream()
    : width(0),
      height(0),
      max_framerate(-1),
      min_bitrate_bps(-1),
      target_bitrate_bps(-1),
      max_bitrate_bps(-1),
      scale_resolution_down_by(-1.),
      max_qp(-1),
      num_temporal_layers(std::nullopt),
      active(true) {}
VideoStream::VideoStream(const VideoStream& other) = default;

VideoStream::~VideoStream() = default;

std::string VideoStream::ToString() const {
  StringBuilder ss;
  ss << "{width: " << width;
  ss << ", height: " << height;
  ss << ", max_framerate: " << max_framerate;
  ss << ", min_bitrate_bps:" << min_bitrate_bps;
  ss << ", target_bitrate_bps:" << target_bitrate_bps;
  ss << ", max_bitrate_bps:" << max_bitrate_bps;
  ss << ", max_qp: " << max_qp;
  ss << ", num_temporal_layers: " << num_temporal_layers.value_or(1);
  ss << ", bitrate_priority: " << bitrate_priority.value_or(0);
  ss << ", active: " << active;
  ss << ", scale_down_by: " << scale_resolution_down_by;
  if (scale_resolution_down_to.has_value()) {
    ss << ", scale_down_to: " << scale_resolution_down_to->width << "x"
       << scale_resolution_down_to->height;
  }
  ss << '}';
  return ss.Release();
}

VideoEncoderConfig::VideoEncoderConfig()
    : codec_type(kVideoCodecGeneric),
      video_format("Unset"),
      content_type(ContentType::kRealtimeVideo),
      frame_drop_enabled(false),
      encoder_specific_settings(nullptr),
      min_transmit_bitrate_bps(0),
      max_bitrate_bps(0),
      bitrate_priority(1.0),
      number_of_streams(0),
      legacy_conference_mode(false),
      is_quality_scaling_allowed(false),
      max_qp(-1) {}

VideoEncoderConfig::VideoEncoderConfig(VideoEncoderConfig&&) = default;

VideoEncoderConfig::~VideoEncoderConfig() = default;

std::string VideoEncoderConfig::ToString() const {
  StringBuilder ss;
  ss << "{codec_type: " << CodecTypeToPayloadString(codec_type);
  ss << ", content_type: ";
  switch (content_type) {
    case ContentType::kRealtimeVideo:
      ss << "kRealtimeVideo";
      break;
    case ContentType::kScreen:
      ss << "kScreenshare";
      break;
  }
  ss << ", frame_drop_enabled: " << frame_drop_enabled;
  ss << ", encoder_specific_settings: ";
  ss << (encoder_specific_settings != nullptr ? "(ptr)" : "NULL");
  ss << ", min_transmit_bitrate_bps: " << min_transmit_bitrate_bps;
  ss << ", number_of_streams: " << number_of_streams;
  ss << ", legacy_conference_mode: " << legacy_conference_mode;
  ss << ", is_quality_scaling_allowed: " << is_quality_scaling_allowed;
  ss << ", max_qp: " << max_qp;
  for (size_t n = 0; n < simulcast_layers.size(); ++n) {
    ss << ", simulcast_layers[" << n << "]: " << simulcast_layers[n].ToString();
  }
  ss << '}';
  return ss.Release();
}

bool VideoEncoderConfig::HasScaleResolutionDownTo() const {
  for (const VideoStream& simulcast_layer : simulcast_layers) {
    if (simulcast_layer.scale_resolution_down_to.has_value()) {
      return true;
    }
  }
  return false;
}

bool VideoEncoderConfig::HasScaleResolutionDownBy() const {
  for (const VideoStream& simulcast_layer : simulcast_layers) {
    if (simulcast_layer.scale_resolution_down_by >= 1.0) {
      return true;
    }
  }
  return false;
}

VideoEncoderConfig::VideoEncoderConfig(const VideoEncoderConfig&) = default;

SdpVideoFormat VideoEncoderConfig::GetSimulcastVideoFormat(
    size_t stream_index) const {
  if (stream_index >= simulcast_layers.size()) {
    return video_format;
  }
  return simulcast_layers[stream_index].video_format.value_or(video_format);
}

void VideoEncoderConfig::EncoderSpecificSettings::FillEncoderSpecificSettings(
    VideoCodec* codec) const {
  if (codec->codecType == kVideoCodecVP8) {
    FillVideoCodecVp8(codec->VP8());
  } else if (codec->codecType == kVideoCodecVP9) {
    FillVideoCodecVp9(codec->VP9());
  } else if (codec->codecType == kVideoCodecAV1) {
    FillVideoCodecAv1(codec->AV1());
  } else {
    RTC_DCHECK_NOTREACHED()
        << "Encoder specifics set/used for unknown codec type.";
  }
}

void VideoEncoderConfig::EncoderSpecificSettings::FillVideoCodecVp8(
    VideoCodecVP8* vp8_settings) const {
  RTC_DCHECK_NOTREACHED();
}

void VideoEncoderConfig::EncoderSpecificSettings::FillVideoCodecVp9(
    VideoCodecVP9* vp9_settings) const {
  RTC_DCHECK_NOTREACHED();
}

void VideoEncoderConfig::EncoderSpecificSettings::FillVideoCodecAv1(
    VideoCodecAV1* av1_settings) const {
  RTC_DCHECK_NOTREACHED();
}

VideoEncoderConfig::Vp8EncoderSpecificSettings::Vp8EncoderSpecificSettings(
    const VideoCodecVP8& specifics)
    : specifics_(specifics) {}

void VideoEncoderConfig::Vp8EncoderSpecificSettings::FillVideoCodecVp8(
    VideoCodecVP8* vp8_settings) const {
  *vp8_settings = specifics_;
}

VideoEncoderConfig::Vp9EncoderSpecificSettings::Vp9EncoderSpecificSettings(
    const VideoCodecVP9& specifics)
    : specifics_(specifics) {}

void VideoEncoderConfig::Vp9EncoderSpecificSettings::FillVideoCodecVp9(
    VideoCodecVP9* vp9_settings) const {
  *vp9_settings = specifics_;
}

VideoEncoderConfig::Av1EncoderSpecificSettings::Av1EncoderSpecificSettings(
    const VideoCodecAV1& specifics)
    : specifics_(specifics) {}

void VideoEncoderConfig::Av1EncoderSpecificSettings::FillVideoCodecAv1(
    VideoCodecAV1* av1_settings) const {
  *av1_settings = specifics_;
}

}  // namespace webrtc
