/*
 *  Copyright (c) 2017 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_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
#define API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_

#include <memory>
#include <optional>
#include <type_traits>
#include <vector>

#include "absl/base/nullability.h"
#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_encoder.h"
#include "api/audio_codecs/audio_encoder_factory.h"
#include "api/audio_codecs/audio_format.h"
#include "api/environment/environment.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"

namespace webrtc {

namespace audio_encoder_factory_template_impl {

template <typename... Ts>
struct Helper;

// Base case: 0 template parameters.
template <>
struct Helper<> {
  static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {}
  static std::optional<AudioCodecInfo> QueryAudioEncoder(
      const SdpAudioFormat& format) {
    return std::nullopt;
  }
  static absl::Nullable<std::unique_ptr<AudioEncoder>> CreateAudioEncoder(
      const Environment& env,
      const SdpAudioFormat& format,
      const AudioEncoderFactory::Options& options) {
    return nullptr;
  }
};

// Use ranked overloads (abseil.io/tips/229) for dispatching.
struct Rank0 {};
struct Rank1 : Rank0 {};

template <typename Trait,
          typename = std::enable_if_t<std::is_convertible_v<
              decltype(Trait::MakeAudioEncoder(
                  std::declval<Environment>(),
                  std::declval<typename Trait::Config>(),
                  std::declval<AudioEncoderFactory::Options>())),
              std::unique_ptr<AudioEncoder>>>>
absl::Nullable<std::unique_ptr<AudioEncoder>> CreateEncoder(
    Rank1,
    const Environment& env,
    const typename Trait::Config& config,
    const AudioEncoderFactory::Options& options) {
  return Trait::MakeAudioEncoder(env, config, options);
}

template <typename Trait,
          typename = std::enable_if_t<std::is_convertible_v<
              decltype(Trait::MakeAudioEncoder(
                  std::declval<typename Trait::Config>(),
                  int{},
                  std::declval<std::optional<AudioCodecPairId>>())),
              std::unique_ptr<AudioEncoder>>>>
absl::Nullable<std::unique_ptr<AudioEncoder>> CreateEncoder(
    Rank0,
    const Environment& env,
    const typename Trait::Config& config,
    const AudioEncoderFactory::Options& options) {
  return Trait::MakeAudioEncoder(config, options.payload_type,
                                 options.codec_pair_id);
}

// Inductive case: Called with n + 1 template parameters; calls subroutines
// with n template parameters.
template <typename T, typename... Ts>
struct Helper<T, Ts...> {
  static void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs) {
    T::AppendSupportedEncoders(specs);
    Helper<Ts...>::AppendSupportedEncoders(specs);
  }
  static std::optional<AudioCodecInfo> QueryAudioEncoder(
      const SdpAudioFormat& format) {
    auto opt_config = T::SdpToConfig(format);
    static_assert(std::is_same<decltype(opt_config),
                               std::optional<typename T::Config>>::value,
                  "T::SdpToConfig() must return a value of type "
                  "std::optional<T::Config>");
    return opt_config ? std::optional<AudioCodecInfo>(
                            T::QueryAudioEncoder(*opt_config))
                      : Helper<Ts...>::QueryAudioEncoder(format);
  }

  static absl::Nullable<std::unique_ptr<AudioEncoder>> CreateAudioEncoder(
      const Environment& env,
      const SdpAudioFormat& format,
      const AudioEncoderFactory::Options& options) {
    if (auto opt_config = T::SdpToConfig(format); opt_config.has_value()) {
      return CreateEncoder<T>(Rank1{}, env, *opt_config, options);
    }
    return Helper<Ts...>::CreateAudioEncoder(env, format, options);
  }
};

template <typename... Ts>
class AudioEncoderFactoryT : public AudioEncoderFactory {
 public:
  std::vector<AudioCodecSpec> GetSupportedEncoders() override {
    std::vector<AudioCodecSpec> specs;
    Helper<Ts...>::AppendSupportedEncoders(&specs);
    return specs;
  }

  std::optional<AudioCodecInfo> QueryAudioEncoder(
      const SdpAudioFormat& format) override {
    return Helper<Ts...>::QueryAudioEncoder(format);
  }

  absl::Nullable<std::unique_ptr<AudioEncoder>> Create(
      const Environment& env,
      const SdpAudioFormat& format,
      Options options) override {
    return Helper<Ts...>::CreateAudioEncoder(env, format, options);
  }
};

}  // namespace audio_encoder_factory_template_impl

// Make an AudioEncoderFactory that can create instances of the given encoders.
//
// Each encoder type is given as a template argument to the function; it should
// be a struct with the following static member functions:
//
//   // Converts `audio_format` to a ConfigType instance. Returns an empty
//   // optional if `audio_format` doesn't correctly specify an encoder of our
//   // type.
//   std::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
//
//   // Appends zero or more AudioCodecSpecs to the list that will be returned
//   // by AudioEncoderFactory::GetSupportedEncoders().
//   void AppendSupportedEncoders(std::vector<AudioCodecSpec>* specs);
//
//   // Returns information about how this format would be encoded. Used to
//   // implement AudioEncoderFactory::QueryAudioEncoder().
//   AudioCodecInfo QueryAudioEncoder(const ConfigType& config);
//
//   // Creates an AudioEncoder for the specified format. Used to implement
//   // AudioEncoderFactory::Create.
//   std::unique_ptr<AudioEncoder> MakeAudioEncoder(
//       const Environment& env,
//       const ConfigType& config,
//       const AudioEncoderFactory::Options& options);
//   or
//   std::unique_ptr<AudioEncoder> MakeAudioEncoder(
//       const ConfigType& config,
//       int payload_type,
//       std::optional<AudioCodecPairId> codec_pair_id);
//
// ConfigType should be a type that encapsulates all the settings needed to
// create an AudioEncoder. T::Config (where T is the encoder struct) should
// either be the config type, or an alias for it.
// When both MakeAudioEncoder signatures are present, 1st one is preferred.
//
// Whenever it tries to do something, the new factory will try each of the
// encoders in the order they were specified in the template argument list,
// stopping at the first one that claims to be able to do the job.
//
// TODO(kwiberg): Point at CreateBuiltinAudioEncoderFactory() for an example of
// how it is used.
template <typename... Ts>
rtc::scoped_refptr<AudioEncoderFactory> CreateAudioEncoderFactory() {
  // There's no technical reason we couldn't allow zero template parameters,
  // but such a factory couldn't create any encoders, and callers can do this
  // by mistake by simply forgetting the <> altogether. So we forbid it in
  // order to prevent caller foot-shooting.
  static_assert(sizeof...(Ts) >= 1,
                "Caller must give at least one template parameter");

  return rtc::make_ref_counted<
      audio_encoder_factory_template_impl::AudioEncoderFactoryT<Ts...>>();
}

}  // namespace webrtc

#endif  // API_AUDIO_CODECS_AUDIO_ENCODER_FACTORY_TEMPLATE_H_
