/*
 *  Copyright (c) 2013 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/acm_receiver.h"

#include <algorithm>  // std::min
#include <memory>

#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "modules/audio_coding/include/audio_coding_module.h"
#include "modules/audio_coding/neteq/tools/rtp_generator.h"
#include "modules/include/module_common_types.h"
#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "system_wrappers/include/clock.h"
#include "test/gtest.h"
#include "test/testsupport/fileutils.h"

namespace webrtc {

namespace acm2 {
namespace {

bool CodecsEqual(const CodecInst& codec_a, const CodecInst& codec_b) {
  if (strcmp(codec_a.plname, codec_b.plname) != 0 ||
      codec_a.plfreq != codec_b.plfreq || codec_a.pltype != codec_b.pltype ||
      codec_b.channels != codec_a.channels)
    return false;
  return true;
}

struct CodecIdInst {
  explicit CodecIdInst(RentACodec::CodecId codec_id) {
    const auto codec_ix = RentACodec::CodecIndexFromId(codec_id);
    EXPECT_TRUE(codec_ix);
    id = *codec_ix;
    const auto codec_inst = RentACodec::CodecInstById(codec_id);
    EXPECT_TRUE(codec_inst);
    inst = *codec_inst;
  }
  int id;
  CodecInst inst;
};

}  // namespace

class AcmReceiverTestOldApi : public AudioPacketizationCallback,
                              public ::testing::Test {
 protected:
  AcmReceiverTestOldApi()
      : timestamp_(0),
        packet_sent_(false),
        last_packet_send_timestamp_(timestamp_),
        last_frame_type_(kEmptyFrame) {
    config_.decoder_factory = CreateBuiltinAudioDecoderFactory();
  }

  ~AcmReceiverTestOldApi() {}

  void SetUp() override {
    acm_.reset(AudioCodingModule::Create(config_));
    receiver_.reset(new AcmReceiver(config_));
    ASSERT_TRUE(receiver_.get() != NULL);
    ASSERT_TRUE(acm_.get() != NULL);
    codecs_ = RentACodec::Database();

    acm_->InitializeReceiver();
    acm_->RegisterTransportCallback(this);

    rtp_header_.header.sequenceNumber = 0;
    rtp_header_.header.timestamp = 0;
    rtp_header_.header.markerBit = false;
    rtp_header_.header.ssrc = 0x12345678;  // Arbitrary.
    rtp_header_.header.numCSRCs = 0;
    rtp_header_.header.payloadType = 0;
    rtp_header_.frameType = kAudioFrameSpeech;
    rtp_header_.type.Audio.isCNG = false;
  }

  void TearDown() override {}

  void InsertOnePacketOfSilence(int codec_id) {
    CodecInst codec =
        *RentACodec::CodecInstById(*RentACodec::CodecIdFromIndex(codec_id));
    if (timestamp_ == 0) {  // This is the first time inserting audio.
      ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
    } else {
      auto current_codec = acm_->SendCodec();
      ASSERT_TRUE(current_codec);
      if (!CodecsEqual(codec, *current_codec))
        ASSERT_EQ(0, acm_->RegisterSendCodec(codec));
    }
    AudioFrame frame;
    // Frame setup according to the codec.
    frame.sample_rate_hz_ = codec.plfreq;
    frame.samples_per_channel_ = codec.plfreq / 100;  // 10 ms.
    frame.num_channels_ = codec.channels;
    frame.Mute();
    packet_sent_ = false;
    last_packet_send_timestamp_ = timestamp_;
    while (!packet_sent_) {
      frame.timestamp_ = timestamp_;
      timestamp_ += rtc::checked_cast<uint32_t>(frame.samples_per_channel_);
      ASSERT_GE(acm_->Add10MsData(frame), 0);
    }
  }

  template <size_t N>
  void AddSetOfCodecs(const RentACodec::CodecId (&ids)[N]) {
    for (auto id : ids) {
      const auto i = RentACodec::CodecIndexFromId(id);
      ASSERT_TRUE(i);
      ASSERT_EQ(0, receiver_->AddCodec(*i, codecs_[*i].pltype,
                                       codecs_[*i].channels, codecs_[*i].plfreq,
                                       nullptr, codecs_[*i].plname));
    }
  }

  int SendData(FrameType frame_type,
               uint8_t payload_type,
               uint32_t timestamp,
               const uint8_t* payload_data,
               size_t payload_len_bytes,
               const RTPFragmentationHeader* fragmentation) override {
    if (frame_type == kEmptyFrame)
      return 0;

    rtp_header_.header.payloadType = payload_type;
    rtp_header_.frameType = frame_type;
    if (frame_type == kAudioFrameSpeech)
      rtp_header_.type.Audio.isCNG = false;
    else
      rtp_header_.type.Audio.isCNG = true;
    rtp_header_.header.timestamp = timestamp;

    int ret_val = receiver_->InsertPacket(
        rtp_header_,
        rtc::ArrayView<const uint8_t>(payload_data, payload_len_bytes));
    if (ret_val < 0) {
      assert(false);
      return -1;
    }
    rtp_header_.header.sequenceNumber++;
    packet_sent_ = true;
    last_frame_type_ = frame_type;
    return 0;
  }

  AudioCodingModule::Config config_;
  std::unique_ptr<AcmReceiver> receiver_;
  rtc::ArrayView<const CodecInst> codecs_;
  std::unique_ptr<AudioCodingModule> acm_;
  WebRtcRTPHeader rtp_header_;
  uint32_t timestamp_;
  bool packet_sent_;  // Set when SendData is called reset when inserting audio.
  uint32_t last_packet_send_timestamp_;
  FrameType last_frame_type_;
};

#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecGetCodec DISABLED_AddCodecGetCodec
#else
#define MAYBE_AddCodecGetCodec AddCodecGetCodec
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecGetCodec) {
  // Add codec.
  for (size_t n = 0; n < codecs_.size(); ++n) {
    if (n & 0x1) {  // Just add codecs with odd index.
      EXPECT_EQ(
          0, receiver_->AddCodec(rtc::checked_cast<int>(n), codecs_[n].pltype,
                                 codecs_[n].channels, codecs_[n].plfreq, NULL,
                                 codecs_[n].plname));
    }
  }
  // Get codec and compare.
  for (size_t n = 0; n < codecs_.size(); ++n) {
    CodecInst my_codec;
    if (n & 0x1) {
      // Codecs with odd index should match the reference.
      EXPECT_EQ(0,
                receiver_->DecoderByPayloadType(codecs_[n].pltype, &my_codec));
      EXPECT_TRUE(CodecsEqual(codecs_[n], my_codec));
    } else {
      // Codecs with even index are not registered.
      EXPECT_EQ(-1,
                receiver_->DecoderByPayloadType(codecs_[n].pltype, &my_codec));
    }
  }
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecChangePayloadType DISABLED_AddCodecChangePayloadType
#else
#define MAYBE_AddCodecChangePayloadType AddCodecChangePayloadType
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecChangePayloadType) {
  const CodecIdInst codec1(RentACodec::CodecId::kPCMA);
  CodecInst codec2 = codec1.inst;
  ++codec2.pltype;
  CodecInst test_codec;

  // Register the same codec with different payloads.
  EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
                                   codec1.inst.channels, codec1.inst.plfreq,
                                   nullptr, codec1.inst.plname));
  EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec2.pltype, codec2.channels,
                                   codec2.plfreq, NULL, codec2.plname));

  // Both payload types should exist.
  EXPECT_EQ(0,
            receiver_->DecoderByPayloadType(codec1.inst.pltype, &test_codec));
  EXPECT_EQ(true, CodecsEqual(codec1.inst, test_codec));
  EXPECT_EQ(0, receiver_->DecoderByPayloadType(codec2.pltype, &test_codec));
  EXPECT_EQ(true, CodecsEqual(codec2, test_codec));
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecChangeCodecId DISABLED_AddCodecChangeCodecId
#else
#define MAYBE_AddCodecChangeCodecId AddCodecChangeCodecId
#endif
TEST_F(AcmReceiverTestOldApi, AddCodecChangeCodecId) {
  const CodecIdInst codec1(RentACodec::CodecId::kPCMU);
  CodecIdInst codec2(RentACodec::CodecId::kPCMA);
  codec2.inst.pltype = codec1.inst.pltype;
  CodecInst test_codec;

  // Register the same payload type with different codec ID.
  EXPECT_EQ(0, receiver_->AddCodec(codec1.id, codec1.inst.pltype,
                                   codec1.inst.channels, codec1.inst.plfreq,
                                   nullptr, codec1.inst.plname));
  EXPECT_EQ(0, receiver_->AddCodec(codec2.id, codec2.inst.pltype,
                                   codec2.inst.channels, codec2.inst.plfreq,
                                   nullptr, codec2.inst.plname));

  // Make sure that the last codec is used.
  EXPECT_EQ(0,
            receiver_->DecoderByPayloadType(codec2.inst.pltype, &test_codec));
  EXPECT_EQ(true, CodecsEqual(codec2.inst, test_codec));
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_AddCodecRemoveCodec DISABLED_AddCodecRemoveCodec
#else
#define MAYBE_AddCodecRemoveCodec AddCodecRemoveCodec
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_AddCodecRemoveCodec) {
  const CodecIdInst codec(RentACodec::CodecId::kPCMA);
  const int payload_type = codec.inst.pltype;
  EXPECT_EQ(
      0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
                             codec.inst.plfreq, nullptr, codec.inst.plname));

  // Remove non-existing codec should not fail. ACM1 legacy.
  EXPECT_EQ(0, receiver_->RemoveCodec(payload_type + 1));

  // Remove an existing codec.
  EXPECT_EQ(0, receiver_->RemoveCodec(payload_type));

  // Ask for the removed codec, must fail.
  CodecInst ci;
  EXPECT_EQ(-1, receiver_->DecoderByPayloadType(payload_type, &ci));
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_SampleRate DISABLED_SampleRate
#else
#define MAYBE_SampleRate SampleRate
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_SampleRate) {
  const RentACodec::CodecId kCodecId[] = {RentACodec::CodecId::kISAC,
                                          RentACodec::CodecId::kISACSWB};
  AddSetOfCodecs(kCodecId);

  AudioFrame frame;
  const int kOutSampleRateHz = 8000;  // Different than codec sample rate.
  for (const auto codec_id : kCodecId) {
    const CodecIdInst codec(codec_id);
    const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
    InsertOnePacketOfSilence(codec.id);
    for (int k = 0; k < num_10ms_frames; ++k) {
      bool muted;
      EXPECT_EQ(0, receiver_->GetAudio(kOutSampleRateHz, &frame, &muted));
    }
    EXPECT_EQ(codec.inst.plfreq, receiver_->last_output_sample_rate_hz());
  }
}

class AcmReceiverTestFaxModeOldApi : public AcmReceiverTestOldApi {
 protected:
  AcmReceiverTestFaxModeOldApi() {
    config_.neteq_config.playout_mode = kPlayoutFax;
  }

  void RunVerifyAudioFrame(RentACodec::CodecId codec_id) {
    // Make sure "fax mode" is enabled. This will avoid delay changes unless the
    // packet-loss concealment is made. We do this in order to make the
    // timestamp increments predictable; in normal mode, NetEq may decide to do
    // accelerate or pre-emptive expand operations after some time, offsetting
    // the timestamp.
    EXPECT_EQ(kPlayoutFax, config_.neteq_config.playout_mode);

    const RentACodec::CodecId kCodecId[] = {codec_id};
    AddSetOfCodecs(kCodecId);

    const CodecIdInst codec(codec_id);
    const int output_sample_rate_hz = codec.inst.plfreq;
    const size_t output_channels = codec.inst.channels;
    const size_t samples_per_ms = rtc::checked_cast<size_t>(
        rtc::CheckedDivExact(output_sample_rate_hz, 1000));
    const int num_10ms_frames = rtc::CheckedDivExact(
        codec.inst.pacsize, rtc::checked_cast<int>(10 * samples_per_ms));
    const AudioFrame::VADActivity expected_vad_activity =
        output_sample_rate_hz > 16000 ? AudioFrame::kVadActive
                                      : AudioFrame::kVadPassive;

    // Expect the first output timestamp to be 5*fs/8000 samples before the
    // first inserted timestamp (because of NetEq's look-ahead). (This value is
    // defined in Expand::overlap_length_.)
    uint32_t expected_output_ts =
        last_packet_send_timestamp_ -
        rtc::CheckedDivExact(5 * output_sample_rate_hz, 8000);

    AudioFrame frame;
    bool muted;
    EXPECT_EQ(0, receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
    // Expect timestamp = 0 before first packet is inserted.
    EXPECT_EQ(0u, frame.timestamp_);
    for (int i = 0; i < 5; ++i) {
      InsertOnePacketOfSilence(codec.id);
      for (int k = 0; k < num_10ms_frames; ++k) {
        EXPECT_EQ(0,
                  receiver_->GetAudio(output_sample_rate_hz, &frame, &muted));
        EXPECT_EQ(expected_output_ts, frame.timestamp_);
        expected_output_ts += rtc::checked_cast<uint32_t>(10 * samples_per_ms);
        EXPECT_EQ(10 * samples_per_ms, frame.samples_per_channel_);
        EXPECT_EQ(output_sample_rate_hz, frame.sample_rate_hz_);
        EXPECT_EQ(output_channels, frame.num_channels_);
        EXPECT_EQ(AudioFrame::kNormalSpeech, frame.speech_type_);
        EXPECT_EQ(expected_vad_activity, frame.vad_activity_);
        EXPECT_FALSE(muted);
      }
    }
  }
};

#if defined(WEBRTC_ANDROID)
#define MAYBE_VerifyAudioFramePCMU DISABLED_VerifyAudioFramePCMU
#else
#define MAYBE_VerifyAudioFramePCMU VerifyAudioFramePCMU
#endif
TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFramePCMU) {
  RunVerifyAudioFrame(RentACodec::CodecId::kPCMU);
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_VerifyAudioFrameISAC DISABLED_VerifyAudioFrameISAC
#else
#define MAYBE_VerifyAudioFrameISAC VerifyAudioFrameISAC
#endif
TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameISAC) {
  RunVerifyAudioFrame(RentACodec::CodecId::kISAC);
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_VerifyAudioFrameOpus DISABLED_VerifyAudioFrameOpus
#else
#define MAYBE_VerifyAudioFrameOpus VerifyAudioFrameOpus
#endif
TEST_F(AcmReceiverTestFaxModeOldApi, MAYBE_VerifyAudioFrameOpus) {
  RunVerifyAudioFrame(RentACodec::CodecId::kOpus);
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
#else
#define MAYBE_PostdecodingVad PostdecodingVad
#endif
TEST_F(AcmReceiverTestOldApi, MAYBE_PostdecodingVad) {
  EXPECT_TRUE(config_.neteq_config.enable_post_decode_vad);
  const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
  ASSERT_EQ(
      0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
                             codec.inst.plfreq, nullptr, ""));
  const int kNumPackets = 5;
  const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
  AudioFrame frame;
  for (int n = 0; n < kNumPackets; ++n) {
    InsertOnePacketOfSilence(codec.id);
    for (int k = 0; k < num_10ms_frames; ++k) {
      bool muted;
      ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted));
    }
  }
  EXPECT_EQ(AudioFrame::kVadPassive, frame.vad_activity_);
}

class AcmReceiverTestPostDecodeVadPassiveOldApi : public AcmReceiverTestOldApi {
 protected:
  AcmReceiverTestPostDecodeVadPassiveOldApi() {
    config_.neteq_config.enable_post_decode_vad = false;
  }
};

#if defined(WEBRTC_ANDROID)
#define MAYBE_PostdecodingVad DISABLED_PostdecodingVad
#else
#define MAYBE_PostdecodingVad PostdecodingVad
#endif
TEST_F(AcmReceiverTestPostDecodeVadPassiveOldApi, MAYBE_PostdecodingVad) {
  EXPECT_FALSE(config_.neteq_config.enable_post_decode_vad);
  const CodecIdInst codec(RentACodec::CodecId::kPCM16Bwb);
  ASSERT_EQ(
      0, receiver_->AddCodec(codec.id, codec.inst.pltype, codec.inst.channels,
                             codec.inst.plfreq, nullptr, ""));
  const int kNumPackets = 5;
  const int num_10ms_frames = codec.inst.pacsize / (codec.inst.plfreq / 100);
  AudioFrame frame;
  for (int n = 0; n < kNumPackets; ++n) {
    InsertOnePacketOfSilence(codec.id);
    for (int k = 0; k < num_10ms_frames; ++k) {
      bool muted;
      ASSERT_EQ(0, receiver_->GetAudio(codec.inst.plfreq, &frame, &muted));
    }
  }
  EXPECT_EQ(AudioFrame::kVadUnknown, frame.vad_activity_);
}

#if defined(WEBRTC_ANDROID)
#define MAYBE_LastAudioCodec DISABLED_LastAudioCodec
#else
#define MAYBE_LastAudioCodec LastAudioCodec
#endif
#if defined(WEBRTC_CODEC_ISAC)
TEST_F(AcmReceiverTestOldApi, MAYBE_LastAudioCodec) {
  const RentACodec::CodecId kCodecId[] = {
      RentACodec::CodecId::kISAC, RentACodec::CodecId::kPCMA,
      RentACodec::CodecId::kISACSWB, RentACodec::CodecId::kPCM16Bswb32kHz};
  AddSetOfCodecs(kCodecId);

  const RentACodec::CodecId kCngId[] = {
      // Not including full-band.
      RentACodec::CodecId::kCNNB, RentACodec::CodecId::kCNWB,
      RentACodec::CodecId::kCNSWB};
  AddSetOfCodecs(kCngId);

  // Register CNG at sender side.
  for (auto id : kCngId)
    ASSERT_EQ(0, acm_->RegisterSendCodec(CodecIdInst(id).inst));

  CodecInst codec;
  // No audio payload is received.
  EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));

  // Start with sending DTX.
  ASSERT_EQ(0, acm_->SetVAD(true, true, VADVeryAggr));
  packet_sent_ = false;
  InsertOnePacketOfSilence(CodecIdInst(kCodecId[0]).id);  // Enough to test
                                                          // with one codec.
  ASSERT_TRUE(packet_sent_);
  EXPECT_EQ(kAudioFrameCN, last_frame_type_);

  // Has received, only, DTX. Last Audio codec is undefined.
  EXPECT_EQ(-1, receiver_->LastAudioCodec(&codec));
  EXPECT_FALSE(receiver_->last_packet_sample_rate_hz());

  for (auto id : kCodecId) {
    const CodecIdInst c(id);

    // Set DTX off to send audio payload.
    acm_->SetVAD(false, false, VADAggr);
    packet_sent_ = false;
    InsertOnePacketOfSilence(c.id);

    // Sanity check if Actually an audio payload received, and it should be
    // of type "speech."
    ASSERT_TRUE(packet_sent_);
    ASSERT_EQ(kAudioFrameSpeech, last_frame_type_);
    EXPECT_EQ(c.inst.plfreq, receiver_->last_packet_sample_rate_hz());

    // Set VAD on to send DTX. Then check if the "Last Audio codec" returns
    // the expected codec.
    acm_->SetVAD(true, true, VADAggr);

    // Do as many encoding until a DTX is sent.
    while (last_frame_type_ != kAudioFrameCN) {
      packet_sent_ = false;
      InsertOnePacketOfSilence(c.id);
      ASSERT_TRUE(packet_sent_);
    }
    EXPECT_EQ(c.inst.plfreq, receiver_->last_packet_sample_rate_hz());
    EXPECT_EQ(0, receiver_->LastAudioCodec(&codec));
    EXPECT_TRUE(CodecsEqual(c.inst, codec));
  }
}
#endif

}  // namespace acm2

}  // namespace webrtc
