/*
 *  Copyright (c) 2014 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/codecs/red/audio_encoder_copy_red.h"

#include <memory>
#include <vector>

#include "rtc_base/checks.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
#include "test/mock_audio_encoder.h"
#include "test/testsupport/rtc_expect_death.h"

using ::testing::_;
using ::testing::Eq;
using ::testing::InSequence;
using ::testing::Invoke;
using ::testing::MockFunction;
using ::testing::Not;
using ::testing::Optional;
using ::testing::Return;
using ::testing::SetArgPointee;

namespace webrtc {

namespace {
static const size_t kMaxNumSamples = 48 * 10 * 2;  // 10 ms @ 48 kHz stereo.
}

class AudioEncoderCopyRedTest : public ::testing::Test {
 protected:
  AudioEncoderCopyRedTest()
      : mock_encoder_(new MockAudioEncoder),
        timestamp_(4711),
        sample_rate_hz_(16000),
        num_audio_samples_10ms(sample_rate_hz_ / 100),
        red_payload_type_(200) {
    AudioEncoderCopyRed::Config config;
    config.payload_type = red_payload_type_;
    config.speech_encoder = std::unique_ptr<AudioEncoder>(mock_encoder_);
    red_.reset(new AudioEncoderCopyRed(std::move(config)));
    memset(audio_, 0, sizeof(audio_));
    EXPECT_CALL(*mock_encoder_, NumChannels()).WillRepeatedly(Return(1U));
    EXPECT_CALL(*mock_encoder_, SampleRateHz())
        .WillRepeatedly(Return(sample_rate_hz_));
  }

  void TearDown() override { red_.reset(); }

  void Encode() {
    ASSERT_TRUE(red_.get() != NULL);
    encoded_.Clear();
    encoded_info_ = red_->Encode(
        timestamp_,
        rtc::ArrayView<const int16_t>(audio_, num_audio_samples_10ms),
        &encoded_);
    timestamp_ += rtc::checked_cast<uint32_t>(num_audio_samples_10ms);
  }

  MockAudioEncoder* mock_encoder_;
  std::unique_ptr<AudioEncoderCopyRed> red_;
  uint32_t timestamp_;
  int16_t audio_[kMaxNumSamples];
  const int sample_rate_hz_;
  size_t num_audio_samples_10ms;
  rtc::Buffer encoded_;
  AudioEncoder::EncodedInfo encoded_info_;
  const int red_payload_type_;
};

TEST_F(AudioEncoderCopyRedTest, CreateAndDestroy) {}

TEST_F(AudioEncoderCopyRedTest, CheckSampleRatePropagation) {
  EXPECT_CALL(*mock_encoder_, SampleRateHz()).WillOnce(Return(17));
  EXPECT_EQ(17, red_->SampleRateHz());
}

TEST_F(AudioEncoderCopyRedTest, CheckNumChannelsPropagation) {
  EXPECT_CALL(*mock_encoder_, NumChannels()).WillOnce(Return(17U));
  EXPECT_EQ(17U, red_->NumChannels());
}

TEST_F(AudioEncoderCopyRedTest, CheckFrameSizePropagation) {
  EXPECT_CALL(*mock_encoder_, Num10MsFramesInNextPacket())
      .WillOnce(Return(17U));
  EXPECT_EQ(17U, red_->Num10MsFramesInNextPacket());
}

TEST_F(AudioEncoderCopyRedTest, CheckMaxFrameSizePropagation) {
  EXPECT_CALL(*mock_encoder_, Max10MsFramesInAPacket()).WillOnce(Return(17U));
  EXPECT_EQ(17U, red_->Max10MsFramesInAPacket());
}

TEST_F(AudioEncoderCopyRedTest, CheckTargetAudioBitratePropagation) {
  EXPECT_CALL(*mock_encoder_,
              OnReceivedUplinkBandwidth(4711, absl::optional<int64_t>()));
  red_->OnReceivedUplinkBandwidth(4711, absl::nullopt);
}

TEST_F(AudioEncoderCopyRedTest, CheckPacketLossFractionPropagation) {
  EXPECT_CALL(*mock_encoder_, OnReceivedUplinkPacketLossFraction(0.5));
  red_->OnReceivedUplinkPacketLossFraction(0.5);
}

TEST_F(AudioEncoderCopyRedTest, CheckGetFrameLengthRangePropagation) {
  auto expected_range =
      std::make_pair(TimeDelta::Millis(20), TimeDelta::Millis(20));
  EXPECT_CALL(*mock_encoder_, GetFrameLengthRange())
      .WillRepeatedly(Return(absl::make_optional(expected_range)));
  EXPECT_THAT(red_->GetFrameLengthRange(), Optional(Eq(expected_range)));
}

// Checks that the an Encode() call is immediately propagated to the speech
// encoder.
TEST_F(AudioEncoderCopyRedTest, CheckImmediateEncode) {
  // Interleaving the EXPECT_CALL sequence with expectations on the MockFunction
  // check ensures that exactly one call to EncodeImpl happens in each
  // Encode call.
  InSequence s;
  MockFunction<void(int check_point_id)> check;
  for (int i = 1; i <= 6; ++i) {
    EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
        .WillRepeatedly(Return(AudioEncoder::EncodedInfo()));
    EXPECT_CALL(check, Call(i));
    Encode();
    check.Call(i);
  }
}

// Checks that no output is produced if the underlying codec doesn't emit any
// new data, even if the RED codec is loaded with a secondary encoding.
TEST_F(AudioEncoderCopyRedTest, CheckNoOutput) {
  static const size_t kEncodedSize = 17;
  static const size_t kHeaderLenBytes = 5;
  {
    InSequence s;
    EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
        .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(kEncodedSize)))
        .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(0)))
        .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(kEncodedSize)));
  }

  // Start with one Encode() call that will produce output.
  Encode();
  // First call is a special case, since it does not include a secondary
  // payload.
  EXPECT_EQ(1u, encoded_info_.redundant.size());
  EXPECT_EQ(kEncodedSize, encoded_info_.encoded_bytes);

  // Next call to the speech encoder will not produce any output.
  Encode();
  EXPECT_EQ(0u, encoded_info_.encoded_bytes);

  // Final call to the speech encoder will produce output.
  Encode();
  EXPECT_EQ(2 * kEncodedSize + kHeaderLenBytes, encoded_info_.encoded_bytes);
  ASSERT_EQ(2u, encoded_info_.redundant.size());
}

// Checks that the correct payload sizes are populated into the redundancy
// information.
TEST_F(AudioEncoderCopyRedTest, CheckPayloadSizes) {
  // Let the mock encoder return payload sizes 1, 2, 3, ..., 10 for the sequence
  // of calls.
  static const int kNumPackets = 10;
  InSequence s;
  for (int encode_size = 1; encode_size <= kNumPackets; ++encode_size) {
    EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
        .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(encode_size)));
  }

  // First call is a special case, since it does not include a secondary
  // payload.
  Encode();
  EXPECT_EQ(1u, encoded_info_.redundant.size());
  EXPECT_EQ(1u, encoded_info_.encoded_bytes);

  // Second call is also special since it does not include a ternary
  // payload.
  Encode();
  EXPECT_EQ(2u, encoded_info_.redundant.size());
  EXPECT_EQ(8u, encoded_info_.encoded_bytes);

  for (size_t i = 3; i <= kNumPackets; ++i) {
    Encode();
    ASSERT_EQ(3u, encoded_info_.redundant.size());
    EXPECT_EQ(i, encoded_info_.redundant[0].encoded_bytes);
    EXPECT_EQ(i - 1, encoded_info_.redundant[1].encoded_bytes);
    EXPECT_EQ(i - 2, encoded_info_.redundant[2].encoded_bytes);
    EXPECT_EQ(9 + i + (i - 1) + (i - 2), encoded_info_.encoded_bytes);
  }
}

// Checks that the correct timestamps are returned.
TEST_F(AudioEncoderCopyRedTest, CheckTimestamps) {
  uint32_t primary_timestamp = timestamp_;
  AudioEncoder::EncodedInfo info;
  info.encoded_bytes = 17;
  info.encoded_timestamp = timestamp_;

  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));

  // First call is a special case, since it does not include a secondary
  // payload.
  Encode();
  EXPECT_EQ(primary_timestamp, encoded_info_.encoded_timestamp);

  uint32_t secondary_timestamp = primary_timestamp;
  primary_timestamp = timestamp_;
  info.encoded_timestamp = timestamp_;
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));

  Encode();
  ASSERT_EQ(2u, encoded_info_.redundant.size());
  EXPECT_EQ(primary_timestamp, encoded_info_.redundant[0].encoded_timestamp);
  EXPECT_EQ(secondary_timestamp, encoded_info_.redundant[1].encoded_timestamp);
  EXPECT_EQ(primary_timestamp, encoded_info_.encoded_timestamp);
}

// Checks that the primary and secondary payloads are written correctly.
TEST_F(AudioEncoderCopyRedTest, CheckPayloads) {
  // Let the mock encoder write payloads with increasing values. The first
  // payload will have values 0, 1, 2, ..., kPayloadLenBytes - 1.
  static const size_t kPayloadLenBytes = 5;
  static const size_t kHeaderLenBytes = 5;
  uint8_t payload[kPayloadLenBytes];
  for (uint8_t i = 0; i < kPayloadLenBytes; ++i) {
    payload[i] = i;
  }
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillRepeatedly(Invoke(MockAudioEncoder::CopyEncoding(payload)));

  // First call is a special case, since it does not include a secondary
  // payload.
  Encode();
  EXPECT_EQ(kPayloadLenBytes, encoded_info_.encoded_bytes);
  for (size_t i = 0; i < kPayloadLenBytes; ++i) {
    EXPECT_EQ(i, encoded_.data()[i]);
  }

  for (int j = 0; j < 1; ++j) {
    // Increment all values of the payload by 10.
    for (size_t i = 0; i < kPayloadLenBytes; ++i)
      payload[i] += 10;

    Encode();
    ASSERT_EQ(2u, encoded_info_.redundant.size());
    EXPECT_EQ(kPayloadLenBytes, encoded_info_.redundant[0].encoded_bytes);
    EXPECT_EQ(kPayloadLenBytes, encoded_info_.redundant[1].encoded_bytes);
    for (size_t i = 0; i < kPayloadLenBytes; ++i) {
      // Check secondary payload.
      EXPECT_EQ(j * 10 + i, encoded_.data()[kHeaderLenBytes + i]);

      // Check primary payload.
      EXPECT_EQ((j + 1) * 10 + i,
                encoded_.data()[kHeaderLenBytes + i + kPayloadLenBytes]);
    }
  }
}

// Checks correct propagation of payload type.
TEST_F(AudioEncoderCopyRedTest, CheckPayloadType) {
  const int primary_payload_type = red_payload_type_ + 1;
  AudioEncoder::EncodedInfo info;
  info.encoded_bytes = 17;
  info.payload_type = primary_payload_type;
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));

  // First call is a special case, since it does not include a secondary
  // payload.
  Encode();
  ASSERT_EQ(1u, encoded_info_.redundant.size());
  EXPECT_EQ(primary_payload_type, encoded_info_.redundant[0].payload_type);
  EXPECT_EQ(primary_payload_type, encoded_info_.payload_type);

  const int secondary_payload_type = red_payload_type_ + 2;
  info.payload_type = secondary_payload_type;
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));

  Encode();
  ASSERT_EQ(2u, encoded_info_.redundant.size());
  EXPECT_EQ(secondary_payload_type, encoded_info_.redundant[0].payload_type);
  EXPECT_EQ(primary_payload_type, encoded_info_.redundant[1].payload_type);
  EXPECT_EQ(red_payload_type_, encoded_info_.payload_type);
}

TEST_F(AudioEncoderCopyRedTest, CheckRFC2198Header) {
  const int primary_payload_type = red_payload_type_ + 1;
  AudioEncoder::EncodedInfo info;
  info.encoded_bytes = 10;
  info.encoded_timestamp = timestamp_;
  info.payload_type = primary_payload_type;

  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();
  info.encoded_timestamp = timestamp_;  // update timestamp.
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();  // Second call will produce a redundant encoding.

  EXPECT_EQ(encoded_.size(),
            5u + 2 * 10u);  // header size + two encoded payloads.
  EXPECT_EQ(encoded_[0], primary_payload_type | 0x80);

  uint32_t timestamp_delta = encoded_info_.encoded_timestamp -
                             encoded_info_.redundant[1].encoded_timestamp;
  // Timestamp delta is encoded as a 14 bit value.
  EXPECT_EQ(encoded_[1], timestamp_delta >> 6);
  EXPECT_EQ(static_cast<uint8_t>(encoded_[2] >> 2), timestamp_delta & 0x3f);
  // Redundant length is encoded as 10 bit value.
  EXPECT_EQ(encoded_[2] & 0x3u, encoded_info_.redundant[1].encoded_bytes >> 8);
  EXPECT_EQ(encoded_[3], encoded_info_.redundant[1].encoded_bytes & 0xff);
  EXPECT_EQ(encoded_[4], primary_payload_type);

  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();  // Third call will produce a redundant encoding with double
             // redundancy.

  EXPECT_EQ(encoded_.size(),
            9u + 3 * 10u);  // header size + two encoded payloads.
  EXPECT_EQ(encoded_[0], primary_payload_type | 0x80);

  timestamp_delta = encoded_info_.encoded_timestamp -
                    encoded_info_.redundant[2].encoded_timestamp;
  // Timestamp delta is encoded as a 14 bit value.
  EXPECT_EQ(encoded_[1], timestamp_delta >> 6);
  EXPECT_EQ(static_cast<uint8_t>(encoded_[2] >> 2), timestamp_delta & 0x3f);
  // Redundant length is encoded as 10 bit value.
  EXPECT_EQ(encoded_[2] & 0x3u, encoded_info_.redundant[2].encoded_bytes >> 8);
  EXPECT_EQ(encoded_[3], encoded_info_.redundant[2].encoded_bytes & 0xff);

  EXPECT_EQ(encoded_[4], primary_payload_type | 0x80);
  timestamp_delta = encoded_info_.encoded_timestamp -
                    encoded_info_.redundant[1].encoded_timestamp;
  // Timestamp delta is encoded as a 14 bit value.
  EXPECT_EQ(encoded_[5], timestamp_delta >> 6);
  EXPECT_EQ(static_cast<uint8_t>(encoded_[6] >> 2), timestamp_delta & 0x3f);
  // Redundant length is encoded as 10 bit value.
  EXPECT_EQ(encoded_[6] & 0x3u, encoded_info_.redundant[2].encoded_bytes >> 8);
  EXPECT_EQ(encoded_[7], encoded_info_.redundant[2].encoded_bytes & 0xff);
  EXPECT_EQ(encoded_[8], primary_payload_type);
}

TEST_F(AudioEncoderCopyRedTest, RespectsPayloadMTU) {
  const int primary_payload_type = red_payload_type_ + 1;
  AudioEncoder::EncodedInfo info;
  info.encoded_bytes = 600;
  info.encoded_timestamp = timestamp_;
  info.payload_type = primary_payload_type;

  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();
  info.encoded_timestamp = timestamp_;  // update timestamp.
  info.encoded_bytes = 500;
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();  // Second call will produce a redundant encoding.

  EXPECT_EQ(encoded_.size(), 5u + 600u + 500u);

  info.encoded_timestamp = timestamp_;  // update timestamp.
  info.encoded_bytes = 400;
  EXPECT_CALL(*mock_encoder_, EncodeImpl(_, _, _))
      .WillOnce(Invoke(MockAudioEncoder::FakeEncoding(info)));
  Encode();  // Third call will drop the oldest packet.
  EXPECT_EQ(encoded_.size(), 5u + 500u + 400u);
}

#if GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

// This test fixture tests various error conditions that makes the
// AudioEncoderCng die via CHECKs.
class AudioEncoderCopyRedDeathTest : public AudioEncoderCopyRedTest {
 protected:
  AudioEncoderCopyRedDeathTest() : AudioEncoderCopyRedTest() {}
};

TEST_F(AudioEncoderCopyRedDeathTest, WrongFrameSize) {
  num_audio_samples_10ms *= 2;  // 20 ms frame.
  RTC_EXPECT_DEATH(Encode(), "");
  num_audio_samples_10ms = 0;  // Zero samples.
  RTC_EXPECT_DEATH(Encode(), "");
}

TEST_F(AudioEncoderCopyRedDeathTest, NullSpeechEncoder) {
  AudioEncoderCopyRed* red = NULL;
  AudioEncoderCopyRed::Config config;
  config.speech_encoder = NULL;
  RTC_EXPECT_DEATH(red = new AudioEncoderCopyRed(std::move(config)),
                   "Speech encoder not provided.");
  // The delete operation is needed to avoid leak reports from memcheck.
  delete red;
}

#endif  // GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

}  // namespace webrtc
