/*
 *  Copyright (c) 2020 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 "api/test/create_peer_connection_quality_test_frame_generator.h"

#include <utility>
#include <vector>

#include "api/test/create_frame_generator.h"
#include "api/test/pclf/media_configuration.h"
#include "rtc_base/checks.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
namespace webrtc_pc_e2e {

void ValidateScreenShareConfig(const VideoConfig& video_config,
                               const ScreenShareConfig& screen_share_config) {
  if (screen_share_config.slides_yuv_file_names.empty()) {
    if (screen_share_config.scrolling_params) {
      // If we have scrolling params, then its `source_width` and `source_heigh`
      // will be used as width and height of video input, so we have to validate
      // it against width and height of default input.
      RTC_CHECK_EQ(screen_share_config.scrolling_params->source_width,
                   kDefaultSlidesWidth);
      RTC_CHECK_EQ(screen_share_config.scrolling_params->source_height,
                   kDefaultSlidesHeight);
    } else {
      RTC_CHECK_EQ(video_config.width, kDefaultSlidesWidth);
      RTC_CHECK_EQ(video_config.height, kDefaultSlidesHeight);
    }
  }
  if (screen_share_config.scrolling_params) {
    RTC_CHECK_LE(screen_share_config.scrolling_params->duration,
                 screen_share_config.slide_change_interval);
    RTC_CHECK_GE(screen_share_config.scrolling_params->source_width,
                 video_config.width);
    RTC_CHECK_GE(screen_share_config.scrolling_params->source_height,
                 video_config.height);
  }
}

std::unique_ptr<test::FrameGeneratorInterface> CreateSquareFrameGenerator(
    const VideoConfig& video_config,
    absl::optional<test::FrameGeneratorInterface::OutputType> type) {
  return test::CreateSquareFrameGenerator(
      video_config.width, video_config.height, std::move(type), absl::nullopt);
}

std::unique_ptr<test::FrameGeneratorInterface> CreateFromYuvFileFrameGenerator(
    const VideoConfig& video_config,
    std::string filename) {
  return test::CreateFromYuvFileFrameGenerator(
      {std::move(filename)}, video_config.width, video_config.height,
      /*frame_repeat_count=*/1);
}

std::unique_ptr<test::FrameGeneratorInterface> CreateScreenShareFrameGenerator(
    const VideoConfig& video_config,
    const ScreenShareConfig& screen_share_config) {
  ValidateScreenShareConfig(video_config, screen_share_config);
  if (screen_share_config.generate_slides) {
    return test::CreateSlideFrameGenerator(
        video_config.width, video_config.height,
        screen_share_config.slide_change_interval.seconds() * video_config.fps);
  }
  std::vector<std::string> slides = screen_share_config.slides_yuv_file_names;
  if (slides.empty()) {
    // If slides is empty we need to add default slides as source. In such case
    // video width and height is validated to be equal to kDefaultSlidesWidth
    // and kDefaultSlidesHeight.
    slides.push_back(test::ResourcePath("web_screenshot_1850_1110", "yuv"));
    slides.push_back(test::ResourcePath("presentation_1850_1110", "yuv"));
    slides.push_back(test::ResourcePath("photo_1850_1110", "yuv"));
    slides.push_back(test::ResourcePath("difficult_photo_1850_1110", "yuv"));
  }
  if (!screen_share_config.scrolling_params) {
    // Cycle image every slide_change_interval seconds.
    return test::CreateFromYuvFileFrameGenerator(
        slides, video_config.width, video_config.height,
        screen_share_config.slide_change_interval.seconds() * video_config.fps);
  }

  TimeDelta pause_duration = screen_share_config.slide_change_interval -
                             screen_share_config.scrolling_params->duration;
  RTC_DCHECK(pause_duration >= TimeDelta::Zero());
  return test::CreateScrollingInputFromYuvFilesFrameGenerator(
      Clock::GetRealTimeClock(), slides,
      screen_share_config.scrolling_params->source_width,
      screen_share_config.scrolling_params->source_height, video_config.width,
      video_config.height, screen_share_config.scrolling_params->duration.ms(),
      pause_duration.ms());
}

}  // namespace webrtc_pc_e2e
}  // namespace webrtc
