/*
 *  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 <memory>

#include "common_types.h"
#include "modules/audio_coding/acm2/rent_a_codec.h"
#include "rtc_base/arraysize.h"
#include "test/gtest.h"
#include "test/mock_audio_encoder.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;

class Marker final {
 public:
  MOCK_METHOD1(Mark, void(std::string desc));
};

}  // namespace

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

  void EncodeAndVerify(size_t expected_out_length,
                       uint32_t expected_timestamp,
                       int expected_payload_type,
                       int expected_send_even_if_empty) {
    rtc::Buffer out;
    AudioEncoder::EncodedInfo encoded_info;
    encoded_info =
        encoder_->Encode(timestamp_, kZeroData, &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_;
  std::unique_ptr<AudioEncoder> encoder_;
  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;
  auto* external_encoder = new MockAudioEncoder;
  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;
  param.speech_encoder = std::unique_ptr<AudioEncoder>(external_encoder);
  std::unique_ptr<AudioEncoder> encoder_stack = rac.RentEncoderStack(&param);
  EXPECT_EQ(external_encoder, encoder_stack.get());
  const int kPacketSizeSamples = kSampleRateHz / 100;
  int16_t audio[kPacketSizeSamples] = {0};
  rtc::Buffer encoded;
  AudioEncoder::EncodedInfo info;

  Marker marker;
  {
    ::testing::InSequence s;
    info.encoded_timestamp = 0;
    EXPECT_CALL(
        *external_encoder,
        EncodeImpl(0, rtc::ArrayView<const int16_t>(audio), &encoded))
        .WillOnce(Return(info));
    EXPECT_CALL(marker, Mark("A"));
    EXPECT_CALL(marker, Mark("B"));
    EXPECT_CALL(marker, Mark("C"));
  }

  info = encoder_stack->Encode(0, audio, &encoded);
  EXPECT_EQ(0u, info.encoded_timestamp);
  marker.Mark("A");

  // Change to internal encoder.
  CodecInst codec_inst = kDefaultCodecInst;
  codec_inst.pacsize = kPacketSizeSamples;
  param.speech_encoder = rac.RentEncoder(codec_inst);
  ASSERT_TRUE(param.speech_encoder);
  AudioEncoder* enc = param.speech_encoder.get();
  std::unique_ptr<AudioEncoder> stack = rac.RentEncoderStack(&param);
  EXPECT_EQ(enc, stack.get());

  // Don't expect any more calls to the external encoder.
  info = stack->Encode(1, audio, &encoded);
  marker.Mark("B");
  encoder_stack.reset();
  marker.Mark("C");
}

// 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) {
  auto make_enc = [] {
    auto speech_encoder =
        std::unique_ptr<MockAudioEncoder>(new MockAudioEncoder);
    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));
    return speech_encoder;
  };
  auto speech_encoder1 = make_enc();
  auto speech_encoder2 = make_enc();
  Marker marker;
  {
    ::testing::InSequence s;
    EXPECT_CALL(marker, Mark("disabled"));
    EXPECT_CALL(marker, Mark("enabled"));
    if (use_cng || use_red)
      EXPECT_CALL(*speech_encoder2, Reset());
  }

  RentACodec::StackParameters param1, param2;
  param1.speech_encoder = std::move(speech_encoder1);
  param2.speech_encoder = std::move(speech_encoder2);
  param2.use_cng = use_cng;
  param2.use_red = use_red;
  marker.Mark("disabled");
  RentACodec rac;
  rac.RentEncoderStack(&param1);
  marker.Mark("enabled");
  rac.RentEncoderStack(&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));
}

TEST(RentACodecTest, RentEncoderStackWithoutSpeechEncoder) {
  RentACodec::StackParameters sp;
  EXPECT_EQ(nullptr, sp.speech_encoder);
  EXPECT_EQ(nullptr, RentACodec().RentEncoderStack(&sp));
}

}  // namespace acm2
}  // namespace webrtc
