/*
 *  Copyright (c) 2015 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 "modules/audio_coding/acm2/rent_a_codec.h"

#include <memory>
#include <utility>

#include "absl/strings/match.h"
#include "modules/audio_coding/codecs/cng/audio_encoder_cng.h"
#include "modules/audio_coding/codecs/g711/audio_encoder_pcm.h"
#include "modules/audio_coding/codecs/g722/audio_encoder_g722.h"
#include "rtc_base/logging.h"
#ifdef WEBRTC_CODEC_ILBC
#include "modules/audio_coding/codecs/ilbc/audio_encoder_ilbc.h"  // nogncheck
#endif
#ifdef WEBRTC_CODEC_ISACFX
#include "modules/audio_coding/codecs/isac/fix/include/audio_decoder_isacfix.h"  // nogncheck
#include "modules/audio_coding/codecs/isac/fix/include/audio_encoder_isacfix.h"  // nogncheck
#endif
#ifdef WEBRTC_CODEC_ISAC
#include "modules/audio_coding/codecs/isac/main/include/audio_decoder_isac.h"  // nogncheck
#include "modules/audio_coding/codecs/isac/main/include/audio_encoder_isac.h"  // nogncheck
#endif
#ifdef WEBRTC_CODEC_OPUS
#include "modules/audio_coding/codecs/opus/audio_encoder_opus.h"
#endif
#include "modules/audio_coding/codecs/pcm16b/audio_encoder_pcm16b.h"
#ifdef WEBRTC_CODEC_RED
#include "modules/audio_coding/codecs/red/audio_encoder_copy_red.h"  // nogncheck
#endif
#include "modules/audio_coding/acm2/acm_codec_database.h"

#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
#include "modules/audio_coding/codecs/isac/locked_bandwidth_info.h"
#endif

namespace webrtc {
namespace acm2 {

absl::optional<RentACodec::CodecId> RentACodec::CodecIdByParams(
    const char* payload_name,
    int sampling_freq_hz,
    size_t channels) {
  return CodecIdFromIndex(
      ACMCodecDB::CodecId(payload_name, sampling_freq_hz, channels));
}

absl::optional<CodecInst> RentACodec::CodecInstById(CodecId codec_id) {
  absl::optional<int> mi = CodecIndexFromId(codec_id);
  return mi ? absl::optional<CodecInst>(Database()[*mi]) : absl::nullopt;
}

absl::optional<RentACodec::CodecId> RentACodec::CodecIdByInst(
    const CodecInst& codec_inst) {
  return CodecIdFromIndex(ACMCodecDB::CodecNumber(codec_inst));
}

absl::optional<CodecInst> RentACodec::CodecInstByParams(
    const char* payload_name,
    int sampling_freq_hz,
    size_t channels) {
  absl::optional<CodecId> codec_id =
      CodecIdByParams(payload_name, sampling_freq_hz, channels);
  if (!codec_id)
    return absl::nullopt;
  absl::optional<CodecInst> ci = CodecInstById(*codec_id);
  RTC_DCHECK(ci);

  // Keep the number of channels from the function call. For most codecs it
  // will be the same value as in default codec settings, but not for all.
  ci->channels = channels;

  return ci;
}

absl::optional<bool> RentACodec::IsSupportedNumChannels(CodecId codec_id,
                                                        size_t num_channels) {
  auto i = CodecIndexFromId(codec_id);
  return i ? absl::optional<bool>(
                 ACMCodecDB::codec_settings_[*i].channel_support >=
                 num_channels)
           : absl::nullopt;
}

rtc::ArrayView<const CodecInst> RentACodec::Database() {
  return rtc::ArrayView<const CodecInst>(ACMCodecDB::database_,
                                         NumberOfCodecs());
}

absl::optional<NetEqDecoder> RentACodec::NetEqDecoderFromCodecId(
    CodecId codec_id,
    size_t num_channels) {
  absl::optional<int> i = CodecIndexFromId(codec_id);
  if (!i)
    return absl::nullopt;
  const NetEqDecoder ned = ACMCodecDB::neteq_decoders_[*i];
  return (ned == NetEqDecoder::kDecoderOpus && num_channels == 2)
             ? NetEqDecoder::kDecoderOpus_2ch
             : ned;
}

RentACodec::RegistrationResult RentACodec::RegisterCngPayloadType(
    std::map<int, int>* pt_map,
    const CodecInst& codec_inst) {
  if (!absl::EqualsIgnoreCase(codec_inst.plname, "CN"))
    return RegistrationResult::kSkip;
  switch (codec_inst.plfreq) {
    case 8000:
    case 16000:
    case 32000:
    case 48000:
      (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
      return RegistrationResult::kOk;
    default:
      return RegistrationResult::kBadFreq;
  }
}

RentACodec::RegistrationResult RentACodec::RegisterRedPayloadType(
    std::map<int, int>* pt_map,
    const CodecInst& codec_inst) {
  if (!absl::EqualsIgnoreCase(codec_inst.plname, "RED"))
    return RegistrationResult::kSkip;
  switch (codec_inst.plfreq) {
    case 8000:
      (*pt_map)[codec_inst.plfreq] = codec_inst.pltype;
      return RegistrationResult::kOk;
    default:
      return RegistrationResult::kBadFreq;
  }
}

namespace {

// Returns a new speech encoder, or null on error.
// TODO(kwiberg): Don't handle errors here (bug 5033)
std::unique_ptr<AudioEncoder> CreateEncoder(
    const CodecInst& speech_inst,
    const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo) {
#if defined(WEBRTC_CODEC_ISACFX)
  if (absl::EqualsIgnoreCase(speech_inst.plname, "isac"))
    return std::unique_ptr<AudioEncoder>(
        new AudioEncoderIsacFixImpl(speech_inst, bwinfo));
#endif
#if defined(WEBRTC_CODEC_ISAC)
  if (absl::EqualsIgnoreCase(speech_inst.plname, "isac"))
    return std::unique_ptr<AudioEncoder>(
        new AudioEncoderIsacFloatImpl(speech_inst, bwinfo));
#endif
#ifdef WEBRTC_CODEC_OPUS
  if (absl::EqualsIgnoreCase(speech_inst.plname, "opus"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderOpusImpl(speech_inst));
#endif
  if (absl::EqualsIgnoreCase(speech_inst.plname, "pcmu"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmU(speech_inst));
  if (absl::EqualsIgnoreCase(speech_inst.plname, "pcma"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderPcmA(speech_inst));
  if (absl::EqualsIgnoreCase(speech_inst.plname, "l16"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderPcm16B(speech_inst));
#ifdef WEBRTC_CODEC_ILBC
  if (absl::EqualsIgnoreCase(speech_inst.plname, "ilbc"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderIlbcImpl(speech_inst));
#endif
  if (absl::EqualsIgnoreCase(speech_inst.plname, "g722"))
    return std::unique_ptr<AudioEncoder>(new AudioEncoderG722Impl(speech_inst));
  RTC_LOG_F(LS_ERROR) << "Could not create encoder of type "
                      << speech_inst.plname;
  return std::unique_ptr<AudioEncoder>();
}

std::unique_ptr<AudioEncoder> CreateRedEncoder(
    std::unique_ptr<AudioEncoder> encoder,
    int red_payload_type) {
#ifdef WEBRTC_CODEC_RED
  AudioEncoderCopyRed::Config config;
  config.payload_type = red_payload_type;
  config.speech_encoder = std::move(encoder);
  return std::unique_ptr<AudioEncoder>(
      new AudioEncoderCopyRed(std::move(config)));
#else
  return std::unique_ptr<AudioEncoder>();
#endif
}

std::unique_ptr<AudioEncoder> CreateCngEncoder(
    std::unique_ptr<AudioEncoder> encoder,
    int payload_type,
    ACMVADMode vad_mode) {
  AudioEncoderCngConfig config;
  config.num_channels = encoder->NumChannels();
  config.payload_type = payload_type;
  config.speech_encoder = std::move(encoder);
  switch (vad_mode) {
    case VADNormal:
      config.vad_mode = Vad::kVadNormal;
      break;
    case VADLowBitrate:
      config.vad_mode = Vad::kVadLowBitrate;
      break;
    case VADAggr:
      config.vad_mode = Vad::kVadAggressive;
      break;
    case VADVeryAggr:
      config.vad_mode = Vad::kVadVeryAggressive;
      break;
    default:
      FATAL();
  }
  return CreateComfortNoiseEncoder(std::move(config));
}

std::unique_ptr<AudioDecoder> CreateIsacDecoder(
    int sample_rate_hz,
    const rtc::scoped_refptr<LockedIsacBandwidthInfo>& bwinfo) {
#if defined(WEBRTC_CODEC_ISACFX)
  return std::unique_ptr<AudioDecoder>(
      new AudioDecoderIsacFixImpl(sample_rate_hz, bwinfo));
#elif defined(WEBRTC_CODEC_ISAC)
  return std::unique_ptr<AudioDecoder>(
      new AudioDecoderIsacFloatImpl(sample_rate_hz, bwinfo));
#else
  FATAL() << "iSAC is not supported.";
  return std::unique_ptr<AudioDecoder>();
#endif
}

}  // namespace

RentACodec::RentACodec() {
#if defined(WEBRTC_CODEC_ISACFX) || defined(WEBRTC_CODEC_ISAC)
  isac_bandwidth_info_ = new LockedIsacBandwidthInfo;
#endif
}
RentACodec::~RentACodec() = default;

std::unique_ptr<AudioEncoder> RentACodec::RentEncoder(
    const CodecInst& codec_inst) {
  return CreateEncoder(codec_inst, isac_bandwidth_info_);
}

RentACodec::StackParameters::StackParameters() {
  // Register the default payload types for RED and CNG.
  for (const CodecInst& ci : RentACodec::Database()) {
    RentACodec::RegisterCngPayloadType(&cng_payload_types, ci);
    RentACodec::RegisterRedPayloadType(&red_payload_types, ci);
  }
}

RentACodec::StackParameters::~StackParameters() = default;

std::unique_ptr<AudioEncoder> RentACodec::RentEncoderStack(
    StackParameters* param) {
  if (!param->speech_encoder)
    return nullptr;

  if (param->use_codec_fec) {
    // Switch FEC on. On failure, remember that FEC is off.
    if (!param->speech_encoder->SetFec(true))
      param->use_codec_fec = false;
  } else {
    // Switch FEC off. This shouldn't fail.
    const bool success = param->speech_encoder->SetFec(false);
    RTC_DCHECK(success);
  }

  auto pt = [&param](const std::map<int, int>& m) {
    auto it = m.find(param->speech_encoder->SampleRateHz());
    return it == m.end() ? absl::nullopt : absl::optional<int>(it->second);
  };
  auto cng_pt = pt(param->cng_payload_types);
  param->use_cng =
      param->use_cng && cng_pt && param->speech_encoder->NumChannels() == 1;
  auto red_pt = pt(param->red_payload_types);
  param->use_red = param->use_red && red_pt;

  if (param->use_cng || param->use_red) {
    // The RED and CNG encoders need to be in sync with the speech encoder, so
    // reset the latter to ensure its buffer is empty.
    param->speech_encoder->Reset();
  }
  std::unique_ptr<AudioEncoder> encoder_stack =
      std::move(param->speech_encoder);
  if (param->use_red) {
    encoder_stack = CreateRedEncoder(std::move(encoder_stack), *red_pt);
  }
  if (param->use_cng) {
    encoder_stack =
        CreateCngEncoder(std::move(encoder_stack), *cng_pt, param->vad_mode);
  }
  return encoder_stack;
}

std::unique_ptr<AudioDecoder> RentACodec::RentIsacDecoder(int sample_rate_hz) {
  return CreateIsacDecoder(sample_rate_hz, isac_bandwidth_info_);
}

}  // namespace acm2
}  // namespace webrtc
