/*
 *  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 "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/arraysize.h"
#include "webrtc/modules/audio_coding/codecs/mock/mock_audio_encoder.h"
#include "webrtc/modules/audio_coding/main/acm2/rent_a_codec.h"

namespace webrtc {
namespace acm2 {

using ::testing::Return;

namespace {
const int kDataLengthSamples = 80;
const int kPacketSizeSamples = 2 * kDataLengthSamples;
const int16_t kZeroData[kDataLengthSamples] = {0};
const CodecInst kDefaultCodecInst = {0, "pcmu", 8000, kPacketSizeSamples,
                                     1, 64000};
const int kCngPt = 13;
}  // namespace

class RentACodecTestF : public ::testing::Test {
 protected:
  void CreateCodec() {
    speech_encoder_ = rent_a_codec_.RentEncoder(kDefaultCodecInst);
    ASSERT_TRUE(speech_encoder_);
    RentACodec::StackParameters param;
    param.use_cng = true;
    encoder_ = rent_a_codec_.RentEncoderStack(speech_encoder_, &param);
  }

  void EncodeAndVerify(size_t expected_out_length,
                       uint32_t expected_timestamp,
                       int expected_payload_type,
                       int expected_send_even_if_empty) {
    uint8_t out[kPacketSizeSamples];
    AudioEncoder::EncodedInfo encoded_info;
    encoded_info =
        encoder_->Encode(timestamp_, kZeroData, kPacketSizeSamples, out);
    timestamp_ += kDataLengthSamples;
    EXPECT_TRUE(encoded_info.redundant.empty());
    EXPECT_EQ(expected_out_length, encoded_info.encoded_bytes);
    EXPECT_EQ(expected_timestamp, encoded_info.encoded_timestamp);
    if (expected_payload_type >= 0)
      EXPECT_EQ(expected_payload_type, encoded_info.payload_type);
    if (expected_send_even_if_empty >= 0)
      EXPECT_EQ(static_cast<bool>(expected_send_even_if_empty),
                encoded_info.send_even_if_empty);
  }

  RentACodec rent_a_codec_;
  AudioEncoder* speech_encoder_ = nullptr;
  AudioEncoder* encoder_ = nullptr;
  uint32_t timestamp_ = 0;
};

// This test verifies that CNG frames are delivered as expected. Since the frame
// size is set to 20 ms, we expect the first encode call to produce no output
// (which is signaled as 0 bytes output of type kNoEncoding). The next encode
// call should produce one SID frame of 9 bytes. The third call should not
// result in any output (just like the first one). The fourth and final encode
// call should produce an "empty frame", which is like no output, but with
// AudioEncoder::EncodedInfo::send_even_if_empty set to true. (The reason to
// produce an empty frame is to drive sending of DTMF packets in the RTP/RTCP
// module.)
TEST_F(RentACodecTestF, VerifyCngFrames) {
  CreateCodec();
  uint32_t expected_timestamp = timestamp_;
  // Verify no frame.
  {
    SCOPED_TRACE("First encoding");
    EncodeAndVerify(0, expected_timestamp, -1, -1);
  }

  // Verify SID frame delivered.
  {
    SCOPED_TRACE("Second encoding");
    EncodeAndVerify(9, expected_timestamp, kCngPt, 1);
  }

  // Verify no frame.
  {
    SCOPED_TRACE("Third encoding");
    EncodeAndVerify(0, expected_timestamp, -1, -1);
  }

  // Verify NoEncoding.
  expected_timestamp += 2 * kDataLengthSamples;
  {
    SCOPED_TRACE("Fourth encoding");
    EncodeAndVerify(0, expected_timestamp, kCngPt, 1);
  }
}

TEST(RentACodecTest, ExternalEncoder) {
  const int kSampleRateHz = 8000;
  MockAudioEncoder external_encoder;
  EXPECT_CALL(external_encoder, SampleRateHz())
      .WillRepeatedly(Return(kSampleRateHz));
  EXPECT_CALL(external_encoder, NumChannels()).WillRepeatedly(Return(1));
  EXPECT_CALL(external_encoder, SetFec(false)).WillRepeatedly(Return(true));

  RentACodec rac;
  RentACodec::StackParameters param;
  EXPECT_EQ(&external_encoder, rac.RentEncoderStack(&external_encoder, &param));
  const int kPacketSizeSamples = kSampleRateHz / 100;
  int16_t audio[kPacketSizeSamples] = {0};
  uint8_t encoded[kPacketSizeSamples];
  AudioEncoder::EncodedInfo info;

  {
    ::testing::InSequence s;
    info.encoded_timestamp = 0;
    EXPECT_CALL(external_encoder,
                EncodeInternal(0, rtc::ArrayView<const int16_t>(audio),
                               arraysize(encoded), encoded))
        .WillOnce(Return(info));
    EXPECT_CALL(external_encoder, Mark("A"));
    EXPECT_CALL(external_encoder, Mark("B"));
    info.encoded_timestamp = 2;
    EXPECT_CALL(external_encoder,
                EncodeInternal(2, rtc::ArrayView<const int16_t>(audio),
                               arraysize(encoded), encoded))
        .WillOnce(Return(info));
    EXPECT_CALL(external_encoder, Die());
  }

  info = rac.GetEncoderStack()->Encode(0, audio, arraysize(encoded), encoded);
  EXPECT_EQ(0u, info.encoded_timestamp);
  external_encoder.Mark("A");

  // Change to internal encoder.
  CodecInst codec_inst = kDefaultCodecInst;
  codec_inst.pacsize = kPacketSizeSamples;
  AudioEncoder* enc = rac.RentEncoder(codec_inst);
  ASSERT_TRUE(enc);
  EXPECT_EQ(enc, rac.RentEncoderStack(enc, &param));

  // Don't expect any more calls to the external encoder.
  info = rac.GetEncoderStack()->Encode(1, audio, arraysize(encoded), encoded);
  external_encoder.Mark("B");

  // Change back to external encoder again.
  EXPECT_EQ(&external_encoder, rac.RentEncoderStack(&external_encoder, &param));
  info = rac.GetEncoderStack()->Encode(2, audio, arraysize(encoded), encoded);
  EXPECT_EQ(2u, info.encoded_timestamp);
}

// Verify that the speech encoder's Reset method is called when CNG or RED
// (or both) are switched on, but not when they're switched off.
void TestCngAndRedResetSpeechEncoder(bool use_cng, bool use_red) {
  MockAudioEncoder speech_encoder;
  EXPECT_CALL(speech_encoder, NumChannels()).WillRepeatedly(Return(1));
  EXPECT_CALL(speech_encoder, Max10MsFramesInAPacket())
      .WillRepeatedly(Return(2));
  EXPECT_CALL(speech_encoder, SampleRateHz()).WillRepeatedly(Return(8000));
  EXPECT_CALL(speech_encoder, SetFec(false)).WillRepeatedly(Return(true));
  {
    ::testing::InSequence s;
    EXPECT_CALL(speech_encoder, Mark("disabled"));
    EXPECT_CALL(speech_encoder, Mark("enabled"));
    if (use_cng || use_red)
      EXPECT_CALL(speech_encoder, Reset());
    EXPECT_CALL(speech_encoder, Die());
  }

  RentACodec::StackParameters param1, param2;
  param2.use_cng = use_cng;
  param2.use_red = use_red;
  speech_encoder.Mark("disabled");
  RentACodec rac;
  rac.RentEncoderStack(&speech_encoder, &param1);
  speech_encoder.Mark("enabled");
  rac.RentEncoderStack(&speech_encoder, &param2);
}

TEST(RentACodecTest, CngResetsSpeechEncoder) {
  TestCngAndRedResetSpeechEncoder(true, false);
}

TEST(RentACodecTest, RedResetsSpeechEncoder) {
  TestCngAndRedResetSpeechEncoder(false, true);
}

TEST(RentACodecTest, CngAndRedResetsSpeechEncoder) {
  TestCngAndRedResetSpeechEncoder(true, true);
}

TEST(RentACodecTest, NoCngAndRedNoSpeechEncoderReset) {
  TestCngAndRedResetSpeechEncoder(false, false);
}

TEST(RentACodecTest, RentEncoderError) {
  const CodecInst codec_inst = {
      0, "Robert'); DROP TABLE Students;", 8000, 160, 1, 64000};
  RentACodec rent_a_codec;
  EXPECT_FALSE(rent_a_codec.RentEncoder(codec_inst));
}

}  // namespace acm2
}  // namespace webrtc
