/*
 *  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_DECODER_FACTORY_TEMPLATE_H_
#define API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_

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

#include "api/audio_codecs/audio_codec_pair_id.h"
#include "api/audio_codecs/audio_decoder.h"
#include "api/audio_codecs/audio_decoder_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_decoder_factory_template_impl {

template <typename... Ts>
struct Helper;

// Base case: 0 template parameters.
template <>
struct Helper<> {
  static void AppendSupportedDecoders(
      std::vector<AudioCodecSpec>* /* specs */) {}
  static bool IsSupportedDecoder(const SdpAudioFormat& /* format */) {
    return false;
  }

  static absl::Nullable<std::unique_ptr<AudioDecoder>> MakeAudioDecoder(
      const Environment& /* env */,
      const SdpAudioFormat& /* format */,
      std::optional<AudioCodecPairId> /* codec_pair_id */) {
    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::MakeAudioDecoder(
                  std::declval<Environment>(),
                  std::declval<typename Trait::Config>(),
                  std::declval<std::optional<AudioCodecPairId>>())),
              std::unique_ptr<AudioDecoder>>>>
absl::Nullable<std::unique_ptr<AudioDecoder>> CreateDecoder(
    Rank1,
    const Environment& env,
    const typename Trait::Config& config,
    std::optional<AudioCodecPairId> codec_pair_id) {
  return Trait::MakeAudioDecoder(env, config, codec_pair_id);
}

template <typename Trait,
          typename = std::enable_if_t<std::is_convertible_v<
              decltype(Trait::MakeAudioDecoder(
                  std::declval<typename Trait::Config>(),
                  std::declval<std::optional<AudioCodecPairId>>())),
              std::unique_ptr<AudioDecoder>>>>
absl::Nullable<std::unique_ptr<AudioDecoder>> CreateDecoder(
    Rank0,
    const Environment& /* env */,
    const typename Trait::Config& config,
    std::optional<AudioCodecPairId> codec_pair_id) {
  return Trait::MakeAudioDecoder(config, 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 AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs) {
    T::AppendSupportedDecoders(specs);
    Helper<Ts...>::AppendSupportedDecoders(specs);
  }
  static bool IsSupportedDecoder(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 ? true : Helper<Ts...>::IsSupportedDecoder(format);
  }

  static absl::Nullable<std::unique_ptr<AudioDecoder>> MakeAudioDecoder(
      const Environment& env,
      const SdpAudioFormat& format,
      std::optional<AudioCodecPairId> codec_pair_id) {
    auto opt_config = T::SdpToConfig(format);
    return opt_config.has_value()
               ? CreateDecoder<T>(Rank1{}, env, *opt_config, codec_pair_id)
               : Helper<Ts...>::MakeAudioDecoder(env, format, codec_pair_id);
  }
};

template <typename... Ts>
class AudioDecoderFactoryT : public AudioDecoderFactory {
 public:
  std::vector<AudioCodecSpec> GetSupportedDecoders() override {
    std::vector<AudioCodecSpec> specs;
    Helper<Ts...>::AppendSupportedDecoders(&specs);
    return specs;
  }

  bool IsSupportedDecoder(const SdpAudioFormat& format) override {
    return Helper<Ts...>::IsSupportedDecoder(format);
  }

  absl::Nullable<std::unique_ptr<AudioDecoder>> Create(
      const Environment& env,
      const SdpAudioFormat& format,
      std::optional<AudioCodecPairId> codec_pair_id) override {
    return Helper<Ts...>::MakeAudioDecoder(env, format, codec_pair_id);
  }
};

}  // namespace audio_decoder_factory_template_impl

// Make an AudioDecoderFactory that can create instances of the given decoders.
//
// Each decoder 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 a decoder of our
//   // type.
//   std::optional<ConfigType> SdpToConfig(const SdpAudioFormat& audio_format);
//
//   // Appends zero or more AudioCodecSpecs to the list that will be returned
//   // by AudioDecoderFactory::GetSupportedDecoders().
//   void AppendSupportedDecoders(std::vector<AudioCodecSpec>* specs);
//
//   // Creates an AudioDecoder for the specified format. Used to implement
//   // AudioDecoderFactory::Create().
//   std::unique_ptr<AudioEncoder> MakeAudioDecoder(
//       const Environment& env,
//       const ConfigType& config,
//       std::optional<AudioCodecPairId> codec_pair_id);
//   or
//   std::unique_ptr<AudioDecoder> MakeAudioDecoder(
//       const ConfigType& config,
//       std::optional<AudioCodecPairId> codec_pair_id);
//
// ConfigType should be a type that encapsulates all the settings needed to
// create an AudioDecoder. T::Config (where T is the decoder struct) should
// either be the config type, or an alias for it.
//
// Whenever it tries to do something, the new factory will try each of the
// decoder types 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 CreateBuiltinAudioDecoderFactory() for an example of
// how it is used.
template <typename... Ts>
scoped_refptr<AudioDecoderFactory> CreateAudioDecoderFactory() {
  // There's no technical reason we couldn't allow zero template parameters,
  // but such a factory couldn't create any decoders, 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 make_ref_counted<
      audio_decoder_factory_template_impl::AudioDecoderFactoryT<Ts...>>();
}

}  // namespace webrtc

#endif  // API_AUDIO_CODECS_AUDIO_DECODER_FACTORY_TEMPLATE_H_
