/*
 *  Copyright (c) 2022 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 API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
#define API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_

#include <memory>
#include <string>
#include <type_traits>
#include <vector>

#include "absl/algorithm/container.h"
#include "api/array_view.h"
#include "api/environment/environment.h"
#include "api/video_codecs/sdp_video_format.h"
#include "api/video_codecs/video_encoder.h"
#include "api/video_codecs/video_encoder_factory.h"
#include "modules/video_coding/svc/scalability_mode_util.h"

namespace webrtc {
// The VideoEncoderFactoryTemplate supports encoders implementations given as
// template arguments.
//
// To include an encoder in the factory it requires three static members
// functions to be defined:
//
//   // Returns the supported SdpVideoFormats this encoder can produce.
//   static std::vector<SdpVideoFormat> SupportedFormats();
//
//   // Creates an encoder instance for the given format.
//   static std::unique_ptr<VideoEncoder>
//       CreateEncoder(const Environment& env,
//                     const SdpVideoFormat& format);
//
//   // Returns true if the encoder supports the given scalability mode.
//   static bool
//       IsScalabilityModeSupported(ScalabilityMode scalability_mode);
//
// Note that the order of the template arguments matter as the factory will
// query/return the first encoder implementation supporting the given
// SdpVideoFormat.
template <typename... Ts>
class VideoEncoderFactoryTemplate : public VideoEncoderFactory {
 public:
  std::vector<SdpVideoFormat> GetSupportedFormats() const override {
    return GetSupportedFormatsInternal<Ts...>();
  }

  std::unique_ptr<VideoEncoder> CreateVideoEncoder(
      const SdpVideoFormat& format) override {
    // We fuzzy match the specified format for both valid and not so valid
    // reasons. The valid reason is that there are many standardized codec
    // specific fmtp parameters that have not been implemented, and in those
    // cases we should not fail to instantiate an encoder just because we don't
    // recognize the parameter. The not so valid reason is that we have started
    // adding parameters completely unrelated to the SDP to the SdpVideoFormat.
    // TODO(bugs.webrtc.org/13868): Remove FuzzyMatchSdpVideoFormat
    absl::optional<SdpVideoFormat> matched =
        FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format);
    return CreateVideoEncoderInternal<Ts...>(matched.value_or(format));
  }

  std::unique_ptr<VideoEncoder> Create(const Environment& env,
                                       const SdpVideoFormat& format) override {
    // We fuzzy match the specified format for both valid and not so valid
    // reasons. The valid reason is that there are many standardized codec
    // specific fmtp parameters that have not been implemented, and in those
    // cases we should not fail to instantiate an encoder just because we don't
    // recognize the parameter. The not so valid reason is that we have started
    // adding parameters completely unrelated to the SDP to the SdpVideoFormat.
    // TODO: bugs.webrtc.org/13868 - Remove FuzzyMatchSdpVideoFormat
    absl::optional<SdpVideoFormat> matched =
        FuzzyMatchSdpVideoFormat(GetSupportedFormats(), format);
    return CreateInternal<Ts...>(env, matched.value_or(format));
  }

  CodecSupport QueryCodecSupport(
      const SdpVideoFormat& format,
      absl::optional<std::string> scalability_mode) const override {
    return QueryCodecSupportInternal<Ts...>(format, scalability_mode);
  }

 private:
  bool IsFormatInList(
      const SdpVideoFormat& format,
      rtc::ArrayView<const SdpVideoFormat> supported_formats) const {
    return absl::c_any_of(
        supported_formats, [&](const SdpVideoFormat& supported_format) {
          return supported_format.name == format.name &&
                 supported_format.parameters == format.parameters;
        });
  }

  template <typename V>
  bool IsScalabilityModeSupported(
      const absl::optional<std::string>& scalability_mode_string) const {
    if (!scalability_mode_string.has_value()) {
      return true;
    }
    absl::optional<ScalabilityMode> scalability_mode =
        ScalabilityModeFromString(*scalability_mode_string);
    return scalability_mode.has_value() &&
           V::IsScalabilityModeSupported(*scalability_mode);
  }

  template <typename V, typename... Vs>
  std::vector<SdpVideoFormat> GetSupportedFormatsInternal() const {
    auto supported_formats = V::SupportedFormats();

    if constexpr (sizeof...(Vs) > 0) {
      // Supported formats may overlap between implementations, so duplicates
      // should be filtered out.
      for (const auto& other_format : GetSupportedFormatsInternal<Vs...>()) {
        if (!IsFormatInList(other_format, supported_formats)) {
          supported_formats.push_back(other_format);
        }
      }
    }

    return supported_formats;
  }

  template <typename V, typename... Vs>
  std::unique_ptr<VideoEncoder> CreateVideoEncoderInternal(
      const SdpVideoFormat& format) {
    if (IsFormatInList(format, V::SupportedFormats())) {
      if constexpr (std::is_invocable_r_v<std::unique_ptr<VideoEncoder>,
                                          decltype(V::CreateEncoder),
                                          const Environment&,
                                          const SdpVideoFormat&>) {
        // Newer code shouldn't call `CreateVideoEncoder` function,
        // Older code should only use traits where Environmnet is not required.
        RTC_CHECK_NOTREACHED();
      } else {
        return V::CreateEncoder(format);
      }
    }

    if constexpr (sizeof...(Vs) > 0) {
      return CreateVideoEncoderInternal<Vs...>(format);
    }

    return nullptr;
  }

  template <typename V, typename... Vs>
  std::unique_ptr<VideoEncoder> CreateInternal(const Environment& env,
                                               const SdpVideoFormat& format) {
    if (IsFormatInList(format, V::SupportedFormats())) {
      if constexpr (std::is_invocable_r_v<std::unique_ptr<VideoEncoder>,
                                          decltype(V::CreateEncoder),
                                          const Environment&,
                                          const SdpVideoFormat&>) {
        return V::CreateEncoder(env, format);
      } else {
        return V::CreateEncoder(format);
      }
    }

    if constexpr (sizeof...(Vs) > 0) {
      return CreateInternal<Vs...>(env, format);
    }

    return nullptr;
  }

  template <typename V, typename... Vs>
  CodecSupport QueryCodecSupportInternal(
      const SdpVideoFormat& format,
      const absl::optional<std::string>& scalability_mode) const {
    if (IsFormatInList(format, V::SupportedFormats())) {
      return {.is_supported = IsScalabilityModeSupported<V>(scalability_mode)};
    }

    if constexpr (sizeof...(Vs) > 0) {
      return QueryCodecSupportInternal<Vs...>(format, scalability_mode);
    }

    return {.is_supported = false};
  }
};

}  // namespace webrtc

#endif  // API_VIDEO_CODECS_VIDEO_ENCODER_FACTORY_TEMPLATE_H_
