/*
 *  Copyright (c) 2018 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_processing/agc2/vad_wrapper.h"

#include <limits>
#include <memory>
#include <tuple>
#include <utility>
#include <vector>

#include "modules/audio_processing/agc2/agc2_common.h"
#include "modules/audio_processing/include/audio_frame_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/gunit.h"
#include "rtc_base/numerics/safe_compare.h"
#include "test/gmock.h"

namespace webrtc {
namespace {

using ::testing::AnyNumber;
using ::testing::Return;
using ::testing::ReturnRoundRobin;
using ::testing::Truly;

constexpr int kNumFramesPerSecond = 100;

constexpr int kNoVadPeriodicReset =
    kFrameDurationMs * (std::numeric_limits<int>::max() / kFrameDurationMs);

constexpr int kSampleRate8kHz = 8000;

class MockVad : public VoiceActivityDetectorWrapper::MonoVad {
 public:
  MOCK_METHOD(int, SampleRateHz, (), (const override));
  MOCK_METHOD(void, Reset, (), (override));
  MOCK_METHOD(float, Analyze, (rtc::ArrayView<const float> frame), (override));
};

// Checks that the ctor and `Initialize()` read the sample rate of the wrapped
// VAD.
TEST(GainController2VoiceActivityDetectorWrapper, CtorAndInitReadSampleRate) {
  auto vad = std::make_unique<MockVad>();
  EXPECT_CALL(*vad, SampleRateHz)
      .Times(2)
      .WillRepeatedly(Return(kSampleRate8kHz));
  EXPECT_CALL(*vad, Reset).Times(AnyNumber());
  auto vad_wrapper = std::make_unique<VoiceActivityDetectorWrapper>(
      kNoVadPeriodicReset, std::move(vad), kSampleRate8kHz);
}

// Creates a `VoiceActivityDetectorWrapper` injecting a mock VAD that
// repeatedly returns the next value from `speech_probabilities` and that
// restarts from the beginning when after the last element is returned.
std::unique_ptr<VoiceActivityDetectorWrapper> CreateMockVadWrapper(
    int vad_reset_period_ms,
    int sample_rate_hz,
    const std::vector<float>& speech_probabilities,
    int expected_vad_reset_calls) {
  auto vad = std::make_unique<MockVad>();
  EXPECT_CALL(*vad, SampleRateHz)
      .Times(AnyNumber())
      .WillRepeatedly(Return(sample_rate_hz));
  if (expected_vad_reset_calls >= 0) {
    EXPECT_CALL(*vad, Reset).Times(expected_vad_reset_calls);
  }
  EXPECT_CALL(*vad, Analyze)
      .Times(AnyNumber())
      .WillRepeatedly(ReturnRoundRobin(speech_probabilities));
  return std::make_unique<VoiceActivityDetectorWrapper>(
      vad_reset_period_ms, std::move(vad), kSampleRate8kHz);
}

// 10 ms mono frame.
struct FrameWithView {
  // Ctor. Initializes the frame samples with `value`.
  explicit FrameWithView(int sample_rate_hz)
      : samples(rtc::CheckedDivExact(sample_rate_hz, kNumFramesPerSecond),
                0.0f),
        channel0(samples.data()),
        view(&channel0, /*num_channels=*/1, samples.size()) {}
  std::vector<float> samples;
  const float* const channel0;
  const AudioFrameView<const float> view;
};

// Checks that the expected speech probabilities are returned.
TEST(GainController2VoiceActivityDetectorWrapper, CheckSpeechProbabilities) {
  const std::vector<float> speech_probabilities{0.709f, 0.484f, 0.882f, 0.167f,
                                                0.44f,  0.525f, 0.858f, 0.314f,
                                                0.653f, 0.965f, 0.413f, 0.0f};
  auto vad_wrapper = CreateMockVadWrapper(kNoVadPeriodicReset, kSampleRate8kHz,
                                          speech_probabilities,
                                          /*expected_vad_reset_calls=*/1);
  FrameWithView frame(kSampleRate8kHz);
  for (int i = 0; rtc::SafeLt(i, speech_probabilities.size()); ++i) {
    SCOPED_TRACE(i);
    EXPECT_EQ(speech_probabilities[i], vad_wrapper->Analyze(frame.view));
  }
}

// Checks that the VAD is not periodically reset.
TEST(GainController2VoiceActivityDetectorWrapper, VadNoPeriodicReset) {
  constexpr int kNumFrames = 19;
  auto vad_wrapper = CreateMockVadWrapper(kNoVadPeriodicReset, kSampleRate8kHz,
                                          /*speech_probabilities=*/{1.0f},
                                          /*expected_vad_reset_calls=*/1);
  FrameWithView frame(kSampleRate8kHz);
  for (int i = 0; i < kNumFrames; ++i) {
    vad_wrapper->Analyze(frame.view);
  }
}

class VadPeriodResetParametrization
    : public ::testing::TestWithParam<std::tuple<int, int>> {
 protected:
  int num_frames() const { return std::get<0>(GetParam()); }
  int vad_reset_period_frames() const { return std::get<1>(GetParam()); }
};

// Checks that the VAD is periodically reset with the expected period.
TEST_P(VadPeriodResetParametrization, VadPeriodicReset) {
  auto vad_wrapper = CreateMockVadWrapper(
      /*vad_reset_period_ms=*/vad_reset_period_frames() * kFrameDurationMs,
      kSampleRate8kHz,
      /*speech_probabilities=*/{1.0f},
      /*expected_vad_reset_calls=*/1 +
          num_frames() / vad_reset_period_frames());
  FrameWithView frame(kSampleRate8kHz);
  for (int i = 0; i < num_frames(); ++i) {
    vad_wrapper->Analyze(frame.view);
  }
}

INSTANTIATE_TEST_SUITE_P(GainController2VoiceActivityDetectorWrapper,
                         VadPeriodResetParametrization,
                         ::testing::Combine(::testing::Values(1, 19, 123),
                                            ::testing::Values(2, 5, 20, 53)));

class VadResamplingParametrization
    : public ::testing::TestWithParam<std::tuple<int, int>> {
 protected:
  int input_sample_rate_hz() const { return std::get<0>(GetParam()); }
  int vad_sample_rate_hz() const { return std::get<1>(GetParam()); }
};

// Checks that regardless of the input audio sample rate, the wrapped VAD
// analyzes frames having the expected size, that is according to its internal
// sample rate.
TEST_P(VadResamplingParametrization, CheckResampledFrameSize) {
  auto vad = std::make_unique<MockVad>();
  EXPECT_CALL(*vad, SampleRateHz)
      .Times(AnyNumber())
      .WillRepeatedly(Return(vad_sample_rate_hz()));
  EXPECT_CALL(*vad, Reset).Times(1);
  EXPECT_CALL(*vad, Analyze(Truly([this](rtc::ArrayView<const float> frame) {
    return rtc::SafeEq(frame.size(), rtc::CheckedDivExact(vad_sample_rate_hz(),
                                                          kNumFramesPerSecond));
  }))).Times(1);
  auto vad_wrapper = std::make_unique<VoiceActivityDetectorWrapper>(
      kNoVadPeriodicReset, std::move(vad), input_sample_rate_hz());
  FrameWithView frame(input_sample_rate_hz());
  vad_wrapper->Analyze(frame.view);
}

INSTANTIATE_TEST_SUITE_P(
    GainController2VoiceActivityDetectorWrapper,
    VadResamplingParametrization,
    ::testing::Combine(::testing::Values(8000, 16000, 44100, 48000),
                       ::testing::Values(6000, 8000, 12000, 16000, 24000)));

}  // namespace
}  // namespace webrtc
