/*
 *  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 <cstddef>
#include <cstdint>
#include <memory>

#include "api/neteq/tick_timer.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 {

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.
constexpr size_t kNetEqSyncBufferLengthMs = 720;
}  // namespace

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 != nullptr);
  delete expand;
}

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(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(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
