/*
 *  Copyright (c) 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 "media/engine/fakewebrtcvideoengine.h"

#include "media/base/codec.h"
#include "media/engine/simulcast_encoder_adapter.h"
#include "media/engine/webrtcvideodecoderfactory.h"
#include "media/engine/webrtcvideoencoderfactory.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "rtc_base/basictypes.h"
#include "rtc_base/gunit.h"
#include "rtc_base/stringutils.h"

namespace cricket {

namespace {

static const int kEventTimeoutMs = 10000;

bool IsFormatSupported(
    const std::vector<webrtc::SdpVideoFormat>& supported_formats,
    const webrtc::SdpVideoFormat& format) {
  for (const webrtc::SdpVideoFormat& supported_format : supported_formats) {
    if (IsSameCodec(format.name, format.parameters, supported_format.name,
                    supported_format.parameters)) {
      return true;
    }
  }
  return false;
}

}  // namespace

// Decoder.
FakeWebRtcVideoDecoder::FakeWebRtcVideoDecoder(
    FakeWebRtcVideoDecoderFactory* factory)
    : num_frames_received_(0), factory_(factory) {}

FakeWebRtcVideoDecoder::~FakeWebRtcVideoDecoder() {
  if (factory_) {
    factory_->DecoderDestroyed(this);
  }
}

int32_t FakeWebRtcVideoDecoder::InitDecode(const webrtc::VideoCodec*, int32_t) {
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoDecoder::Decode(const webrtc::EncodedImage&,
                                       bool,
                                       const webrtc::CodecSpecificInfo*,
                                       int64_t) {
  num_frames_received_++;
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoDecoder::RegisterDecodeCompleteCallback(
    webrtc::DecodedImageCallback*) {
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoDecoder::Release() {
  return WEBRTC_VIDEO_CODEC_OK;
}

int FakeWebRtcVideoDecoder::GetNumFramesReceived() const {
  return num_frames_received_;
}

// Decoder factory.
FakeWebRtcVideoDecoderFactory::FakeWebRtcVideoDecoderFactory()
    : num_created_decoders_(0) {}

std::vector<webrtc::SdpVideoFormat>
FakeWebRtcVideoDecoderFactory::GetSupportedFormats() const {
  std::vector<webrtc::SdpVideoFormat> formats;

  for (const webrtc::SdpVideoFormat& format : supported_codec_formats_) {
    // Don't add same codec twice.
    if (!IsFormatSupported(formats, format))
      formats.push_back(format);
  }

  return formats;
}

std::unique_ptr<webrtc::VideoDecoder>
FakeWebRtcVideoDecoderFactory::CreateVideoDecoder(
    const webrtc::SdpVideoFormat& format) {
  if (IsFormatSupported(supported_codec_formats_, format)) {
    num_created_decoders_++;
    std::unique_ptr<FakeWebRtcVideoDecoder> decoder =
        rtc::MakeUnique<FakeWebRtcVideoDecoder>(this);
    decoders_.push_back(decoder.get());
    return decoder;
  }

  return nullptr;
}

void FakeWebRtcVideoDecoderFactory::DecoderDestroyed(
    FakeWebRtcVideoDecoder* decoder) {
  decoders_.erase(std::remove(decoders_.begin(), decoders_.end(), decoder),
                  decoders_.end());
}

void FakeWebRtcVideoDecoderFactory::AddSupportedVideoCodecType(
    const webrtc::SdpVideoFormat& format) {
  supported_codec_formats_.push_back(format);
}

int FakeWebRtcVideoDecoderFactory::GetNumCreatedDecoders() {
  return num_created_decoders_;
}

const std::vector<FakeWebRtcVideoDecoder*>&
FakeWebRtcVideoDecoderFactory::decoders() {
  return decoders_;
}

// Encoder.
FakeWebRtcVideoEncoder::FakeWebRtcVideoEncoder(
    FakeWebRtcVideoEncoderFactory* factory)
    : init_encode_event_(false, false),
      num_frames_encoded_(0),
      factory_(factory) {}

FakeWebRtcVideoEncoder::~FakeWebRtcVideoEncoder() {
  if (factory_) {
    factory_->EncoderDestroyed(this);
  }
}

int32_t FakeWebRtcVideoEncoder::InitEncode(
    const webrtc::VideoCodec* codecSettings,
    int32_t numberOfCores,
    size_t maxPayloadSize) {
  rtc::CritScope lock(&crit_);
  codec_settings_ = *codecSettings;
  init_encode_event_.Set();
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoEncoder::Encode(
    const webrtc::VideoFrame& inputImage,
    const webrtc::CodecSpecificInfo* codecSpecificInfo,
    const std::vector<webrtc::FrameType>* frame_types) {
  rtc::CritScope lock(&crit_);
  ++num_frames_encoded_;
  init_encode_event_.Set();
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoEncoder::RegisterEncodeCompleteCallback(
    webrtc::EncodedImageCallback* callback) {
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoEncoder::Release() {
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoEncoder::SetChannelParameters(uint32_t packetLoss,
                                                     int64_t rtt) {
  return WEBRTC_VIDEO_CODEC_OK;
}

int32_t FakeWebRtcVideoEncoder::SetRateAllocation(
    const webrtc::VideoBitrateAllocation& allocation,
    uint32_t framerate) {
  return WEBRTC_VIDEO_CODEC_OK;
}

bool FakeWebRtcVideoEncoder::WaitForInitEncode() {
  return init_encode_event_.Wait(kEventTimeoutMs);
}

webrtc::VideoCodec FakeWebRtcVideoEncoder::GetCodecSettings() {
  rtc::CritScope lock(&crit_);
  return codec_settings_;
}

int FakeWebRtcVideoEncoder::GetNumEncodedFrames() {
  rtc::CritScope lock(&crit_);
  return num_frames_encoded_;
}

// Video encoder factory.
FakeWebRtcVideoEncoderFactory::FakeWebRtcVideoEncoderFactory()
    : created_video_encoder_event_(false, false),
      num_created_encoders_(0),
      encoders_have_internal_sources_(false),
      vp8_factory_mode_(false) {}

std::vector<webrtc::SdpVideoFormat>
FakeWebRtcVideoEncoderFactory::GetSupportedFormats() const {
  std::vector<webrtc::SdpVideoFormat> formats;

  for (const webrtc::SdpVideoFormat& format : formats_) {
    // Don't add same codec twice.
    if (!IsFormatSupported(formats, format))
      formats.push_back(format);
  }

  return formats;
}

std::unique_ptr<webrtc::VideoEncoder>
FakeWebRtcVideoEncoderFactory::CreateVideoEncoder(
    const webrtc::SdpVideoFormat& format) {
  rtc::CritScope lock(&crit_);
  std::unique_ptr<webrtc::VideoEncoder> encoder;
  if (IsFormatSupported(formats_, format)) {
    if (CodecNamesEq(format.name.c_str(), kVp8CodecName) &&
        !vp8_factory_mode_) {
      // The simulcast adapter will ask this factory for multiple VP8
      // encoders. Enter vp8_factory_mode so that we now create these encoders
      // instead of more adapters.
      vp8_factory_mode_ = true;
      encoder = rtc::MakeUnique<webrtc::SimulcastEncoderAdapter>(this);
    } else {
      num_created_encoders_++;
      created_video_encoder_event_.Set();
      encoder = rtc::MakeUnique<FakeWebRtcVideoEncoder>(this);
      encoders_.push_back(static_cast<FakeWebRtcVideoEncoder*>(encoder.get()));
    }
  }
  return encoder;
}

webrtc::VideoEncoderFactory::CodecInfo
FakeWebRtcVideoEncoderFactory::QueryVideoEncoder(
    const webrtc::SdpVideoFormat& format) const {
  webrtc::VideoEncoderFactory::CodecInfo info;
  info.has_internal_source = encoders_have_internal_sources_;
  info.is_hardware_accelerated = true;
  return info;
}

bool FakeWebRtcVideoEncoderFactory::WaitForCreatedVideoEncoders(
    int num_encoders) {
  int64_t start_offset_ms = rtc::TimeMillis();
  int64_t wait_time = kEventTimeoutMs;
  do {
    if (GetNumCreatedEncoders() >= num_encoders)
      return true;
    wait_time = kEventTimeoutMs - (rtc::TimeMillis() - start_offset_ms);
  } while (wait_time > 0 && created_video_encoder_event_.Wait(wait_time));
  return false;
}

void FakeWebRtcVideoEncoderFactory::EncoderDestroyed(
    FakeWebRtcVideoEncoder* encoder) {
  rtc::CritScope lock(&crit_);
  encoders_.erase(std::remove(encoders_.begin(), encoders_.end(), encoder),
                  encoders_.end());
}

void FakeWebRtcVideoEncoderFactory::set_encoders_have_internal_sources(
    bool internal_source) {
  encoders_have_internal_sources_ = internal_source;
}

void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodec(
    const webrtc::SdpVideoFormat& format) {
  formats_.push_back(format);
}

void FakeWebRtcVideoEncoderFactory::AddSupportedVideoCodecType(
    const std::string& name) {
  // This is to match the default H264 params of cricket::VideoCodec.
  cricket::VideoCodec video_codec(name);
  formats_.push_back(
      webrtc::SdpVideoFormat(video_codec.name, video_codec.params));
}

int FakeWebRtcVideoEncoderFactory::GetNumCreatedEncoders() {
  rtc::CritScope lock(&crit_);
  return num_created_encoders_;
}

const std::vector<FakeWebRtcVideoEncoder*>
FakeWebRtcVideoEncoderFactory::encoders() {
  rtc::CritScope lock(&crit_);
  return encoders_;
}

}  // namespace cricket
