/*
 *  Copyright (c) 2016 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/aec3/block_processor.h"

#include <memory>
#include <string>
#include <vector>

#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/mock/mock_echo_remover.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_buffer.h"
#include "modules/audio_processing/aec3/mock/mock_render_delay_controller.h"
#include "modules/audio_processing/test/echo_canceller_test_tools.h"
#include "rtc_base/checks.h"
#include "rtc_base/random.h"
#include "rtc_base/strings/string_builder.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

using ::testing::_;
using ::testing::AtLeast;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::StrictMock;

// Verifies that the basic BlockProcessor functionality works and that the API
// methods are callable.
void RunBasicSetupAndApiCallTest(const Environment& env,
                                 int sample_rate_hz,
                                 int num_iterations) {
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;

  std::unique_ptr<BlockProcessor> block_processor =
      BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
                             kNumRenderChannels, kNumCaptureChannels);
  Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels, 1000.f);
  for (int k = 0; k < num_iterations; ++k) {
    block_processor->BufferRender(block);
    block_processor->ProcessCapture(false, false, nullptr, &block);
    block_processor->UpdateEchoLeakageStatus(false);
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
void RunRenderBlockSizeVerificationTest(const Environment& env,
                                        int sample_rate_hz) {
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;

  std::unique_ptr<BlockProcessor> block_processor =
      BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
                             kNumRenderChannels, kNumCaptureChannels);
  Block block(NumBandsForRate(sample_rate_hz), kNumRenderChannels);

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunRenderNumBandsVerificationTest(const Environment& env,
                                       int sample_rate_hz) {
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;

  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor =
      BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
                             kNumRenderChannels, kNumCaptureChannels);
  Block block(wrong_num_bands, kNumRenderChannels);

  EXPECT_DEATH(block_processor->BufferRender(block), "");
}

void RunCaptureNumBandsVerificationTest(const Environment& env,
                                        int sample_rate_hz) {
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;

  const size_t wrong_num_bands = NumBandsForRate(sample_rate_hz) < 3
                                     ? NumBandsForRate(sample_rate_hz) + 1
                                     : 1;
  std::unique_ptr<BlockProcessor> block_processor =
      BlockProcessor::Create(env, EchoCanceller3Config(), sample_rate_hz,
                             kNumRenderChannels, kNumCaptureChannels);
  Block block(wrong_num_bands, kNumRenderChannels);

  EXPECT_DEATH(block_processor->ProcessCapture(false, false, nullptr, &block),
               "");
}
#endif

std::string ProduceDebugText(int sample_rate_hz) {
  StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.Release();
}

void FillSampleVector(int call_counter,
                      int delay,
                      rtc::ArrayView<float> samples) {
  for (size_t i = 0; i < samples.size(); ++i) {
    samples[i] = (call_counter - delay) * 10000.0f + i;
  }
}

}  // namespace

// Verifies that the delay controller functionality is properly integrated with
// the render delay buffer inside block processor.
// TODO(peah): Activate the unittest once the required code has been landed.
TEST(BlockProcessor, DISABLED_DelayControllerIntegration) {
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;
  constexpr size_t kNumBlocks = 310;
  constexpr size_t kDelayInSamples = 640;
  constexpr size_t kDelayHeadroom = 1;
  constexpr size_t kDelayInBlocks =
      kDelayInSamples / kBlockSize - kDelayHeadroom;
  const Environment env = CreateEnvironment();
  Random random_generator(42U);
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(kDelayInBlocks))
        .Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, MaxDelay()).WillOnce(Return(30));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks + 1)
        .WillRepeatedly(Return(0));
    std::unique_ptr<BlockProcessor> block_processor = BlockProcessor::Create(
        env, EchoCanceller3Config(), rate, kNumRenderChannels,
        kNumCaptureChannels, std::move(render_delay_buffer_mock));

    Block render_block(NumBandsForRate(rate), kNumRenderChannels);
    Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
    DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator,
                            render_block.View(/*band=*/0, /*capture=*/0));
      signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
                                capture_block.View(/*band=*/0, /*capture=*/0));
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, nullptr, &capture_block);
    }
  }
}

// Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
  constexpr size_t kNumBlocks = 310;
  constexpr size_t kNumRenderChannels = 1;
  constexpr size_t kNumCaptureChannels = 1;

  Random random_generator(42U);
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<webrtc::test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<webrtc::test::MockRenderDelayBuffer>(rate, 1));
    std::unique_ptr<
        ::testing::StrictMock<webrtc::test::MockRenderDelayController>>
        render_delay_controller_mock(
            new StrictMock<webrtc::test::MockRenderDelayController>());
    std::unique_ptr<testing::StrictMock<webrtc::test::MockEchoRemover>>
        echo_remover_mock(new StrictMock<webrtc::test::MockEchoRemover>());

    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks - 1)
        .WillRepeatedly(Return(RenderDelayBuffer::BufferingEvent::kNone));
    EXPECT_CALL(*render_delay_buffer_mock, PrepareCaptureProcessing())
        .Times(kNumBlocks);
    EXPECT_CALL(*render_delay_buffer_mock, AlignFromDelay(9)).Times(AtLeast(1));
    EXPECT_CALL(*render_delay_buffer_mock, Delay())
        .Times(kNumBlocks)
        .WillRepeatedly(Return(0));
    EXPECT_CALL(*render_delay_controller_mock, GetDelay(_, _, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, ProcessCapture(_, _, _, _, _, _))
        .Times(kNumBlocks);
    EXPECT_CALL(*echo_remover_mock, UpdateEchoLeakageStatus(_))
        .Times(kNumBlocks);

    std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
        EchoCanceller3Config(), rate, kNumRenderChannels, kNumCaptureChannels,
        std::move(render_delay_buffer_mock),
        std::move(render_delay_controller_mock), std::move(echo_remover_mock)));

    Block render_block(NumBandsForRate(rate), kNumRenderChannels);
    Block capture_block(NumBandsForRate(rate), kNumCaptureChannels);
    DelayBuffer<float> signal_delay_buffer(640);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator,
                            render_block.View(/*band=*/0, /*capture=*/0));
      signal_delay_buffer.Delay(render_block.View(/*band=*/0, /*capture=*/0),
                                capture_block.View(/*band=*/0, /*capture=*/0));
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, nullptr, &capture_block);
      block_processor->UpdateEchoLeakageStatus(false);
    }
  }
}

TEST(BlockProcessor, BasicSetupAndApiCalls) {
  const Environment env = CreateEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunBasicSetupAndApiCallTest(env, rate, 1);
  }
}

TEST(BlockProcessor, TestLongerCall) {
  RunBasicSetupAndApiCallTest(CreateEnvironment(), 16000,
                              20 * kNumBlocksPerSecond);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
// TODO(gustaf): Re-enable the test once the issue with memory leaks during
// DEATH tests on test bots has been fixed.
TEST(BlockProcessorDeathTest, DISABLED_VerifyRenderBlockSizeCheck) {
  const Environment env = CreateEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderBlockSizeVerificationTest(env, rate);
  }
}

TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
  const Environment env = CreateEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderNumBandsVerificationTest(env, rate);
  }
}

// TODO(peah): Verify the check for correct number of bands in the capture
// signal.
TEST(BlockProcessorDeathTest, VerifyCaptureNumBandsCheck) {
  const Environment env = CreateEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureNumBandsVerificationTest(env, rate);
  }
}

// Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessorDeathTest, NullProcessCaptureParameter) {
  EXPECT_DEATH(BlockProcessor::Create(CreateEnvironment(),
                                      EchoCanceller3Config(), 16000, 1, 1)
                   ->ProcessCapture(false, false, nullptr, nullptr),
               "");
}

// Verifies the check for correct sample rate.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(BlockProcessor, DISABLED_WrongSampleRate) {
  EXPECT_DEATH(BlockProcessor::Create(CreateEnvironment(),
                                      EchoCanceller3Config(), 8001, 1, 1),
               "");
}

#endif

// Verifies that external delay estimator delays are applied correctly when a
// call begins with a sequence of capture blocks.
TEST(BlockProcessor, ExternalDelayAppliedCorrectlyWithInitialCaptureCalls) {
  constexpr int kNumRenderChannels = 1;
  constexpr int kNumCaptureChannels = 1;
  constexpr int kSampleRateHz = 16000;

  EchoCanceller3Config config;
  config.delay.use_external_delay_estimator = true;

  std::unique_ptr<RenderDelayBuffer> delay_buffer(
      RenderDelayBuffer::Create(config, kSampleRateHz, kNumRenderChannels));

  std::unique_ptr<testing::NiceMock<webrtc::test::MockEchoRemover>>
      echo_remover_mock(new NiceMock<webrtc::test::MockEchoRemover>());
  webrtc::test::MockEchoRemover* echo_remover_mock_pointer =
      echo_remover_mock.get();

  std::unique_ptr<BlockProcessor> block_processor(BlockProcessor::Create(
      config, kSampleRateHz, kNumRenderChannels, kNumCaptureChannels,
      std::move(delay_buffer), /*delay_controller=*/nullptr,
      std::move(echo_remover_mock)));

  Block render_block(NumBandsForRate(kSampleRateHz), kNumRenderChannels);
  Block capture_block(NumBandsForRate(kSampleRateHz), kNumCaptureChannels);

  // Process...
  // - 10 capture calls, where no render data is available,
  // - 10 render calls, populating the buffer,
  // - 2 capture calls, verifying that the delay was applied correctly.
  constexpr int kDelayInBlocks = 5;
  constexpr int kDelayInMs = 20;
  block_processor->SetAudioBufferDelay(kDelayInMs);

  int capture_call_counter = 0;
  int render_call_counter = 0;
  for (size_t k = 0; k < 10; ++k) {
    FillSampleVector(++capture_call_counter, kDelayInBlocks,
                     capture_block.View(/*band=*/0, /*capture=*/0));
    block_processor->ProcessCapture(false, false, nullptr, &capture_block);
  }
  for (size_t k = 0; k < 10; ++k) {
    FillSampleVector(++render_call_counter, 0,
                     render_block.View(/*band=*/0, /*capture=*/0));
    block_processor->BufferRender(render_block);
  }

  EXPECT_CALL(*echo_remover_mock_pointer, ProcessCapture)
      .WillRepeatedly([](EchoPathVariability /*echo_path_variability*/,
                         bool /*capture_signal_saturation*/,
                         const std::optional<DelayEstimate>& /*external_delay*/,
                         RenderBuffer* render_buffer, Block* /*linear_output*/,
                         Block* capture) {
        const auto& render = render_buffer->GetBlock(0);
        const auto render_view = render.View(/*band=*/0, /*channel=*/0);
        const auto capture_view = capture->View(/*band=*/0, /*channel=*/0);
        for (size_t i = 0; i < kBlockSize; ++i) {
          EXPECT_FLOAT_EQ(render_view[i], capture_view[i]);
        }
      });

  FillSampleVector(++capture_call_counter, kDelayInBlocks,
                   capture_block.View(/*band=*/0, /*capture=*/0));
  block_processor->ProcessCapture(false, false, nullptr, &capture_block);

  FillSampleVector(++capture_call_counter, kDelayInBlocks,
                   capture_block.View(/*band=*/0, /*capture=*/0));
  block_processor->ProcessCapture(false, false, nullptr, &capture_block);
}

}  // namespace webrtc
