/*
 *  Copyright (c) 2017 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/render_delay_controller.h"

#include <algorithm>
#include <cstddef>
#include <memory>
#include <optional>
#include <string>
#include <vector>

#include "api/audio/echo_canceller3_config.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/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/gtest.h"

namespace webrtc {
namespace {

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

std::string ProduceDebugText(int sample_rate_hz,
                             size_t delay,
                             size_t num_render_channels,
                             size_t num_capture_channels) {
  StringBuilder ss;
  ss << ProduceDebugText(sample_rate_hz) << ", Delay: " << delay
     << ", Num render channels: " << num_render_channels
     << ", Num capture channels: " << num_capture_channels;
  return ss.Release();
}

constexpr size_t kDownSamplingFactors[] = {4, 8};

}  // namespace

// Verifies the output of GetDelay when there are no AnalyzeRender calls.
// TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController, DISABLED_NoRenderSignal) {
  for (size_t num_render_channels : {1, 2, 8}) {
    Block block(/*num_bands=1*/ 1, /*num_channels=*/1);
    EchoCanceller3Config config;
    for (size_t num_matched_filters = 4; num_matched_filters <= 10;
         num_matched_filters++) {
      for (auto down_sampling_factor : kDownSamplingFactors) {
        config.delay.down_sampling_factor = down_sampling_factor;
        config.delay.num_filters = num_matched_filters;
        for (auto rate : {16000, 32000, 48000}) {
          SCOPED_TRACE(ProduceDebugText(rate));
          std::unique_ptr<RenderDelayBuffer> delay_buffer(
              RenderDelayBuffer::Create(config, rate, num_render_channels));
          std::unique_ptr<RenderDelayController> delay_controller(
              RenderDelayController::Create(config, rate,
                                            /*num_capture_channels*/ 1));
          for (size_t k = 0; k < 100; ++k) {
            auto delay = delay_controller->GetDelay(
                delay_buffer->GetDownsampledRenderBuffer(),
                delay_buffer->Delay(), block);
            EXPECT_FALSE(delay->delay);
          }
        }
      }
    }
  }
}

// Verifies the basic API call sequence.
// TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController, DISABLED_BasicApiCalls) {
  for (size_t num_capture_channels : {1, 2, 4}) {
    for (size_t num_render_channels : {1, 2, 8}) {
      Block capture_block(/*num_bands=*/1, num_capture_channels);
      std::optional<DelayEstimate> delay_blocks;
      for (size_t num_matched_filters = 4; num_matched_filters <= 10;
           num_matched_filters++) {
        for (auto down_sampling_factor : kDownSamplingFactors) {
          EchoCanceller3Config config;
          config.delay.down_sampling_factor = down_sampling_factor;
          config.delay.num_filters = num_matched_filters;
          config.delay.capture_alignment_mixing.downmix = false;
          config.delay.capture_alignment_mixing.adaptive_selection = false;

          for (auto rate : {16000, 32000, 48000}) {
            Block render_block(NumBandsForRate(rate), num_render_channels);
            std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
                RenderDelayBuffer::Create(config, rate, num_render_channels));
            std::unique_ptr<RenderDelayController> delay_controller(
                RenderDelayController::Create(EchoCanceller3Config(), rate,
                                              num_capture_channels));
            for (size_t k = 0; k < 10; ++k) {
              render_delay_buffer->Insert(render_block);
              render_delay_buffer->PrepareCaptureProcessing();

              delay_blocks = delay_controller->GetDelay(
                  render_delay_buffer->GetDownsampledRenderBuffer(),
                  render_delay_buffer->Delay(), capture_block);
            }
            EXPECT_TRUE(delay_blocks);
            EXPECT_FALSE(delay_blocks->delay);
          }
        }
      }
    }
  }
}

// Verifies that the RenderDelayController is able to align the signals for
// simple timeshifts between the signals.
// TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController, DISABLED_Alignment) {
  Random random_generator(42U);
  for (size_t num_capture_channels : {1, 2, 4}) {
    Block capture_block(/*num_bands=*/1, num_capture_channels);
    for (size_t num_matched_filters = 4; num_matched_filters <= 10;
         num_matched_filters++) {
      for (auto down_sampling_factor : kDownSamplingFactors) {
        EchoCanceller3Config config;
        config.delay.down_sampling_factor = down_sampling_factor;
        config.delay.num_filters = num_matched_filters;
        config.delay.capture_alignment_mixing.downmix = false;
        config.delay.capture_alignment_mixing.adaptive_selection = false;

        for (size_t num_render_channels : {1, 2, 8}) {
          for (auto rate : {16000, 32000, 48000}) {
            Block render_block(NumBandsForRate(rate), num_render_channels);

            for (size_t delay_samples : {15, 50, 150, 200, 800, 4000}) {
              std::optional<DelayEstimate> delay_blocks;
              SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
                                            num_render_channels,
                                            num_capture_channels));
              std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
                  RenderDelayBuffer::Create(config, rate, num_render_channels));
              std::unique_ptr<RenderDelayController> delay_controller(
                  RenderDelayController::Create(config, rate,
                                                num_capture_channels));
              DelayBuffer<float> signal_delay_buffer(delay_samples);
              for (size_t k = 0; k < (400 + delay_samples / kBlockSize); ++k) {
                for (int band = 0; band < render_block.NumBands(); ++band) {
                  for (int channel = 0; channel < render_block.NumChannels();
                       ++channel) {
                    RandomizeSampleVector(&random_generator,
                                          render_block.View(band, channel));
                  }
                }
                signal_delay_buffer.Delay(
                    render_block.View(/*band=*/0, /*channel=*/0),
                    capture_block.View(/*band=*/0, /*channel=*/0));
                render_delay_buffer->Insert(render_block);
                render_delay_buffer->PrepareCaptureProcessing();
                delay_blocks = delay_controller->GetDelay(
                    render_delay_buffer->GetDownsampledRenderBuffer(),
                    render_delay_buffer->Delay(), capture_block);
              }
              ASSERT_TRUE(!!delay_blocks);

              constexpr int kDelayHeadroomBlocks = 1;
              size_t expected_delay_blocks =
                  std::max(0, static_cast<int>(delay_samples / kBlockSize) -
                                  kDelayHeadroomBlocks);

              EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
            }
          }
        }
      }
    }
  }
}

// Verifies that the RenderDelayController is able to properly handle noncausal
// delays.
// TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController, DISABLED_NonCausalAlignment) {
  Random random_generator(42U);
  for (size_t num_capture_channels : {1, 2, 4}) {
    for (size_t num_render_channels : {1, 2, 8}) {
      for (size_t num_matched_filters = 4; num_matched_filters <= 10;
           num_matched_filters++) {
        for (auto down_sampling_factor : kDownSamplingFactors) {
          EchoCanceller3Config config;
          config.delay.down_sampling_factor = down_sampling_factor;
          config.delay.num_filters = num_matched_filters;
          config.delay.capture_alignment_mixing.downmix = false;
          config.delay.capture_alignment_mixing.adaptive_selection = false;
          for (auto rate : {16000, 32000, 48000}) {
            Block render_block(NumBandsForRate(rate), num_render_channels);
            Block capture_block(NumBandsForRate(rate), num_capture_channels);

            for (int delay_samples : {-15, -50, -150, -200}) {
              std::optional<DelayEstimate> delay_blocks;
              SCOPED_TRACE(ProduceDebugText(rate, -delay_samples,
                                            num_render_channels,
                                            num_capture_channels));
              std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
                  RenderDelayBuffer::Create(config, rate, num_render_channels));
              std::unique_ptr<RenderDelayController> delay_controller(
                  RenderDelayController::Create(EchoCanceller3Config(), rate,
                                                num_capture_channels));
              DelayBuffer<float> signal_delay_buffer(-delay_samples);
              for (int k = 0;
                   k < (400 - delay_samples / static_cast<int>(kBlockSize));
                   ++k) {
                RandomizeSampleVector(
                    &random_generator,
                    capture_block.View(/*band=*/0, /*channel=*/0));
                signal_delay_buffer.Delay(
                    capture_block.View(/*band=*/0, /*channel=*/0),
                    render_block.View(/*band=*/0, /*channel=*/0));
                render_delay_buffer->Insert(render_block);
                render_delay_buffer->PrepareCaptureProcessing();
                delay_blocks = delay_controller->GetDelay(
                    render_delay_buffer->GetDownsampledRenderBuffer(),
                    render_delay_buffer->Delay(), capture_block);
              }

              ASSERT_FALSE(delay_blocks);
            }
          }
        }
      }
    }
  }
}

// Verifies that the RenderDelayController is able to align the signals for
// simple timeshifts between the signals when there is jitter in the API calls.
// TODO(bugs.webrtc.org/11161): Re-enable tests.
TEST(RenderDelayController, DISABLED_AlignmentWithJitter) {
  Random random_generator(42U);
  for (size_t num_capture_channels : {1, 2, 4}) {
    for (size_t num_render_channels : {1, 2, 8}) {
      Block capture_block(
          /*num_bands=*/1, num_capture_channels);
      for (size_t num_matched_filters = 4; num_matched_filters <= 10;
           num_matched_filters++) {
        for (auto down_sampling_factor : kDownSamplingFactors) {
          EchoCanceller3Config config;
          config.delay.down_sampling_factor = down_sampling_factor;
          config.delay.num_filters = num_matched_filters;
          config.delay.capture_alignment_mixing.downmix = false;
          config.delay.capture_alignment_mixing.adaptive_selection = false;

          for (auto rate : {16000, 32000, 48000}) {
            Block render_block(NumBandsForRate(rate), num_render_channels);
            for (size_t delay_samples : {15, 50, 300, 800}) {
              std::optional<DelayEstimate> delay_blocks;
              SCOPED_TRACE(ProduceDebugText(rate, delay_samples,
                                            num_render_channels,
                                            num_capture_channels));
              std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
                  RenderDelayBuffer::Create(config, rate, num_render_channels));
              std::unique_ptr<RenderDelayController> delay_controller(
                  RenderDelayController::Create(config, rate,
                                                num_capture_channels));
              DelayBuffer<float> signal_delay_buffer(delay_samples);
              constexpr size_t kMaxTestJitterBlocks = 26;
              for (size_t j = 0; j < (1000 + delay_samples / kBlockSize) /
                                             kMaxTestJitterBlocks +
                                         1;
                   ++j) {
                std::vector<Block> capture_block_buffer;
                for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
                  RandomizeSampleVector(
                      &random_generator,
                      render_block.View(/*band=*/0, /*channel=*/0));
                  signal_delay_buffer.Delay(
                      render_block.View(/*band=*/0, /*channel=*/0),
                      capture_block.View(/*band=*/0, /*channel=*/0));
                  capture_block_buffer.push_back(capture_block);
                  render_delay_buffer->Insert(render_block);
                }
                for (size_t k = 0; k < (kMaxTestJitterBlocks - 1); ++k) {
                  render_delay_buffer->PrepareCaptureProcessing();
                  delay_blocks = delay_controller->GetDelay(
                      render_delay_buffer->GetDownsampledRenderBuffer(),
                      render_delay_buffer->Delay(), capture_block_buffer[k]);
                }
              }

              constexpr int kDelayHeadroomBlocks = 1;
              size_t expected_delay_blocks =
                  std::max(0, static_cast<int>(delay_samples / kBlockSize) -
                                  kDelayHeadroomBlocks);
              if (expected_delay_blocks < 2) {
                expected_delay_blocks = 0;
              }

              ASSERT_TRUE(delay_blocks);
              EXPECT_EQ(expected_delay_blocks, delay_blocks->delay);
            }
          }
        }
      }
    }
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

// 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(RenderDelayControllerDeathTest, DISABLED_WrongSampleRate) {
  for (auto rate : {-1, 0, 8001, 16001}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    EchoCanceller3Config config;
    std::unique_ptr<RenderDelayBuffer> render_delay_buffer(
        RenderDelayBuffer::Create(config, rate, 1));
    EXPECT_DEATH(
        std::unique_ptr<RenderDelayController>(
            RenderDelayController::Create(EchoCanceller3Config(), rate, 1)),
        "");
  }
}

#endif

}  // namespace webrtc
