/*
 *  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 <sstream>
#include <string>
#include <vector>

#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 "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace {

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

// Verifies that the basic BlockProcessor functionality works and that the API
// methods are callable.
void RunBasicSetupAndApiCallTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(NumBandsForRate(sample_rate_hz),
                                        std::vector<float>(kBlockSize, 0.f));

  block_processor->BufferRender(block);
  block_processor->ProcessCapture(false, false, &block);
  block_processor->UpdateEchoLeakageStatus(false);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
void RunRenderBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

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

void RunCaptureBlockSizeVerificationTest(int sample_rate_hz) {
  std::unique_ptr<BlockProcessor> block_processor(
      BlockProcessor::Create(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(
      NumBandsForRate(sample_rate_hz), std::vector<float>(kBlockSize - 1, 0.f));

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

void RunRenderNumBandsVerificationTest(int sample_rate_hz) {
  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(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

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

void RunCaptureNumBandsVerificationTest(int sample_rate_hz) {
  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(EchoCanceller3Config(), sample_rate_hz));
  std::vector<std::vector<float>> block(wrong_num_bands,
                                        std::vector<float>(kBlockSize, 0.f));

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

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

}  // 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 kNumBlocks = 310;
  constexpr size_t kDelayInSamples = 640;
  constexpr size_t kDelayHeadroom = 1;
  constexpr size_t kDelayInBlocks =
      kDelayInSamples / kBlockSize - kDelayHeadroom;
  Random random_generator(42U);
  for (auto rate : {8000, 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));
    EXPECT_CALL(*render_delay_buffer_mock, Insert(_))
        .Times(kNumBlocks)
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*render_delay_buffer_mock, IsBlockAvailable())
        .Times(kNumBlocks)
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(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(
        EchoCanceller3Config(), rate, std::move(render_delay_buffer_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(kDelayInSamples);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
    }
  }
}

// Verifies that BlockProcessor submodules are called in a proper manner.
TEST(BlockProcessor, DISABLED_SubmoduleIntegration) {
  constexpr size_t kNumBlocks = 310;
  Random random_generator(42U);
  for (auto rate : {8000, 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));
    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(true));
    EXPECT_CALL(*render_delay_buffer_mock, IsBlockAvailable())
        .Times(kNumBlocks)
        .WillRepeatedly(Return(true));
    EXPECT_CALL(*render_delay_buffer_mock, UpdateBuffers()).Times(kNumBlocks);
    EXPECT_CALL(*render_delay_buffer_mock, SetDelay(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)
        .WillRepeatedly(Return(9));
    EXPECT_CALL(*render_delay_controller_mock, AlignmentHeadroomSamples())
        .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, std::move(render_delay_buffer_mock),
        std::move(render_delay_controller_mock), std::move(echo_remover_mock)));

    std::vector<std::vector<float>> render_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    std::vector<std::vector<float>> capture_block(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    DelayBuffer<float> signal_delay_buffer(640);
    for (size_t k = 0; k < kNumBlocks; ++k) {
      RandomizeSampleVector(&random_generator, render_block[0]);
      signal_delay_buffer.Delay(render_block[0], capture_block[0]);
      block_processor->BufferRender(render_block);
      block_processor->ProcessCapture(false, false, &capture_block);
      block_processor->UpdateEchoLeakageStatus(false);
    }
  }
}

TEST(BlockProcessor, BasicSetupAndApiCalls) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunBasicSetupAndApiCallTest(rate);
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(BlockProcessor, VerifyRenderBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyCaptureBlockSizeCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunCaptureBlockSizeVerificationTest(rate);
  }
}

TEST(BlockProcessor, VerifyRenderNumBandsCheck) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    RunRenderNumBandsVerificationTest(rate);
  }
}

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

// Verifiers that the verification for null ProcessCapture input works.
TEST(BlockProcessor, NullProcessCaptureParameter) {
  EXPECT_DEATH(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8000))
                   ->ProcessCapture(false, false, 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(std::unique_ptr<BlockProcessor>(
                   BlockProcessor::Create(EchoCanceller3Config(), 8001)),
               "");
}

#endif

}  // namespace webrtc
