/*
 *  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 <cstddef>
#include <memory>
#include <optional>
#include <span>
#include <string>
#include <utility>

#include "api/audio/echo_canceller3_config.h"
#include "api/environment/environment.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/aec3/block.h"
#include "modules/audio_processing/aec3/delay_estimate.h"
#include "modules/audio_processing/aec3/echo_path_variability.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/aec3/render_buffer.h"
#include "modules/audio_processing/aec3/render_delay_buffer.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/create_test_environment.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, /*neural_residual_echo_estimator=*/nullptr);
  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, /*neural_residual_echo_estimator=*/nullptr);
  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, /*neural_residual_echo_estimator=*/nullptr);
  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, /*neural_residual_echo_estimator=*/nullptr);
  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, std::span<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 = CreateTestEnvironment();
  Random random_generator(42U);
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<testing::StrictMock<test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<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),
        /*neural_residual_echo_estimator=*/nullptr);

    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<test::MockRenderDelayBuffer>>
        render_delay_buffer_mock(
            new StrictMock<test::MockRenderDelayBuffer>(rate, 1));
    std::unique_ptr<::testing::StrictMock<test::MockRenderDelayController>>
        render_delay_controller_mock(
            new StrictMock<test::MockRenderDelayController>());
    std::unique_ptr<testing::StrictMock<test::MockEchoRemover>>
        echo_remover_mock(new StrictMock<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 = CreateTestEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunBasicSetupAndApiCallTest(env, rate, 1);
  }
}

TEST(BlockProcessor, TestLongerCall) {
  RunBasicSetupAndApiCallTest(CreateTestEnvironment(), 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 = CreateTestEnvironment();
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderBlockSizeVerificationTest(env, rate);
  }
}

TEST(BlockProcessorDeathTest, VerifyRenderNumBandsCheck) {
  const Environment env = CreateTestEnvironment();
  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 = CreateTestEnvironment();
  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(
                   CreateTestEnvironment(), EchoCanceller3Config(), 16000, 1, 1,
                   /*neural_residual_echo_estimator=*/nullptr)
                   ->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(
                   CreateTestEnvironment(), EchoCanceller3Config(), 8001, 1, 1,
                   /*neural_residual_echo_estimator=*/nullptr),
               "");
}

#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<test::MockEchoRemover>> echo_remover_mock(
      new NiceMock<test::MockEchoRemover>());
  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