/*
 *  Copyright (c) 2012 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.
 */

// Unit tests for Expand class.

#include "modules/audio_coding/neteq/expand.h"

#include "common_audio/signal_processing/include/signal_processing_library.h"
#include "modules/audio_coding/neteq/background_noise.h"
#include "modules/audio_coding/neteq/random_vector.h"
#include "modules/audio_coding/neteq/statistics_calculator.h"
#include "modules/audio_coding/neteq/sync_buffer.h"
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {

TEST(Expand, CreateAndDestroy) {
  int fs = 8000;
  size_t channels = 1;
  BackgroundNoise bgn(channels);
  SyncBuffer sync_buffer(1, 1000);
  RandomVector random_vector;
  TickTimer timer;
  StatisticsCalculator statistics(&timer);
  Expand expand(&bgn, &sync_buffer, &random_vector, &statistics, fs, channels);
}

TEST(Expand, CreateUsingFactory) {
  int fs = 8000;
  size_t channels = 1;
  BackgroundNoise bgn(channels);
  SyncBuffer sync_buffer(1, 1000);
  RandomVector random_vector;
  TickTimer timer;
  StatisticsCalculator statistics(&timer);
  ExpandFactory expand_factory;
  Expand* expand = expand_factory.Create(&bgn, &sync_buffer, &random_vector,
                                         &statistics, fs, channels);
  EXPECT_TRUE(expand != NULL);
  delete expand;
}

namespace {
class FakeStatisticsCalculator : public StatisticsCalculator {
 public:
  FakeStatisticsCalculator(TickTimer* tick_timer)
      : StatisticsCalculator(tick_timer) {}

  void LogDelayedPacketOutageEvent(int num_samples, int /* fs_hz */) override {
    last_outage_duration_samples_ = num_samples;
  }

  int last_outage_duration_samples() const {
    return last_outage_duration_samples_;
  }

 private:
  int last_outage_duration_samples_ = 0;
};

// This is the same size that is given to the SyncBuffer object in NetEq.
const size_t kNetEqSyncBufferLengthMs = 720;
}  // namespace

class ExpandTest : public ::testing::Test {
 protected:
  ExpandTest()
      : input_file_(test::ResourcePath("audio_coding/testfile32kHz", "pcm"),
                    32000),
        test_sample_rate_hz_(32000),
        num_channels_(1),
        background_noise_(num_channels_),
        sync_buffer_(num_channels_,
                     kNetEqSyncBufferLengthMs * test_sample_rate_hz_ / 1000),
        statistics_(&tick_timer_),
        expand_(&background_noise_,
                &sync_buffer_,
                &random_vector_,
                &statistics_,
                test_sample_rate_hz_,
                num_channels_) {
    input_file_.set_output_rate_hz(test_sample_rate_hz_);
  }

  void SetUp() override {
    // Fast-forward the input file until there is speech (about 1.1 second into
    // the file).
    const int speech_start_samples =
        static_cast<int>(test_sample_rate_hz_ * 1.1f);
    ASSERT_TRUE(input_file_.Seek(speech_start_samples));

    // Pre-load the sync buffer with speech data.
    std::unique_ptr<int16_t[]> temp(new int16_t[sync_buffer_.Size()]);
    ASSERT_TRUE(input_file_.Read(sync_buffer_.Size(), temp.get()));
    sync_buffer_.Channel(0).OverwriteAt(temp.get(), sync_buffer_.Size(), 0);
    ASSERT_EQ(1u, num_channels_) << "Fix: Must populate all channels.";
  }

  test::ResampleInputAudioFile input_file_;
  int test_sample_rate_hz_;
  size_t num_channels_;
  BackgroundNoise background_noise_;
  SyncBuffer sync_buffer_;
  RandomVector random_vector_;
  TickTimer tick_timer_;
  FakeStatisticsCalculator statistics_;
  Expand expand_;
};

// This test calls the expand object to produce concealment data a few times,
// and then ends by calling SetParametersForNormalAfterExpand. This simulates
// the situation where the packet next up for decoding was just delayed, not
// lost.
TEST_F(ExpandTest, DelayedPacketOutage) {
  AudioMultiVector output(num_channels_);
  size_t sum_output_len_samples = 0;
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(0, expand_.Process(&output));
    EXPECT_GT(output.Size(), 0u);
    sum_output_len_samples += output.Size();
    EXPECT_EQ(0, statistics_.last_outage_duration_samples());
  }
  expand_.SetParametersForNormalAfterExpand();
  // Convert `sum_output_len_samples` to milliseconds.
  EXPECT_EQ(rtc::checked_cast<int>(sum_output_len_samples),
            statistics_.last_outage_duration_samples());
}

// This test is similar to DelayedPacketOutage, but ends by calling
// SetParametersForMergeAfterExpand. This simulates the situation where the
// packet next up for decoding was actually lost (or at least a later packet
// arrived before it).
TEST_F(ExpandTest, LostPacketOutage) {
  AudioMultiVector output(num_channels_);
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(0, expand_.Process(&output));
    EXPECT_GT(output.Size(), 0u);
    EXPECT_EQ(0, statistics_.last_outage_duration_samples());
  }
  expand_.SetParametersForMergeAfterExpand();
  EXPECT_EQ(0, statistics_.last_outage_duration_samples());
}

// This test is similar to the DelayedPacketOutage test above, but with the
// difference that Expand::Reset() is called after 5 calls to Expand::Process().
// This should reset the statistics, and will in the end lead to an outage of
// 5 periods instead of 10.
TEST_F(ExpandTest, CheckOutageStatsAfterReset) {
  AudioMultiVector output(num_channels_);
  size_t sum_output_len_samples = 0;
  for (int i = 0; i < 10; ++i) {
    EXPECT_EQ(0, expand_.Process(&output));
    EXPECT_GT(output.Size(), 0u);
    sum_output_len_samples += output.Size();
    if (i == 5) {
      expand_.Reset();
      sum_output_len_samples = 0;
    }
    EXPECT_EQ(0, statistics_.last_outage_duration_samples());
  }
  expand_.SetParametersForNormalAfterExpand();
  // Convert `sum_output_len_samples` to milliseconds.
  EXPECT_EQ(rtc::checked_cast<int>(sum_output_len_samples),
            statistics_.last_outage_duration_samples());
}

namespace {
// Runs expand until Muted() returns true. Times out after 1000 calls.
void ExpandUntilMuted(size_t num_channels, Expand* expand) {
  EXPECT_FALSE(expand->Muted()) << "Instance is muted from the start";
  AudioMultiVector output(num_channels);
  int num_calls = 0;
  while (!expand->Muted()) {
    ASSERT_LT(num_calls++, 1000) << "Test timed out";
    EXPECT_EQ(0, expand->Process(&output));
  }
}
}  // namespace

// Verifies that Muted() returns true after a long expand period. Also verifies
// that Muted() is reset to false after calling Reset(),
// SetParametersForMergeAfterExpand() and SetParametersForNormalAfterExpand().
TEST_F(ExpandTest, Muted) {
  ExpandUntilMuted(num_channels_, &expand_);
  expand_.Reset();
  EXPECT_FALSE(expand_.Muted());  // Should be back to unmuted.

  ExpandUntilMuted(num_channels_, &expand_);
  expand_.SetParametersForMergeAfterExpand();
  EXPECT_FALSE(expand_.Muted());  // Should be back to unmuted.

  expand_.Reset();  // Must reset in order to start a new expand period.
  ExpandUntilMuted(num_channels_, &expand_);
  expand_.SetParametersForNormalAfterExpand();
  EXPECT_FALSE(expand_.Muted());  // Should be back to unmuted.
}

// TODO(hlundin): Write more tests.

}  // namespace webrtc
