/*
 *  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_buffer.h"

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

#include "api/array_view.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "modules/audio_processing/logging/apm_data_dumper.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) {
  rtc::StringBuilder ss;
  ss << "Sample rate: " << sample_rate_hz;
  return ss.Release();
}

}  // namespace

// Verifies that the buffer overflow is correctly reported.
TEST(RenderDelayBuffer, BufferOverflow) {
  const EchoCanceller3Config config;
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<RenderDelayBuffer> delay_buffer(
        RenderDelayBuffer::Create2(config, NumBandsForRate(rate)));
    std::vector<std::vector<float>> block_to_insert(
        NumBandsForRate(rate), std::vector<float>(kBlockSize, 0.f));
    for (size_t k = 0; k < 10; ++k) {
      EXPECT_EQ(RenderDelayBuffer::BufferingEvent::kNone,
                delay_buffer->Insert(block_to_insert));
    }
    bool overrun_occurred = false;
    for (size_t k = 0; k < 1000; ++k) {
      RenderDelayBuffer::BufferingEvent event =
          delay_buffer->Insert(block_to_insert);
      overrun_occurred =
          overrun_occurred ||
          RenderDelayBuffer::BufferingEvent::kRenderOverrun == event;
    }

    EXPECT_TRUE(overrun_occurred);
  }
}

// Verifies that the check for available block works.
TEST(RenderDelayBuffer, AvailableBlock) {
  constexpr size_t kNumBands = 1;
  std::unique_ptr<RenderDelayBuffer> delay_buffer(
      RenderDelayBuffer::Create2(EchoCanceller3Config(), kNumBands));
  std::vector<std::vector<float>> input_block(
      kNumBands, std::vector<float>(kBlockSize, 1.f));
  EXPECT_EQ(RenderDelayBuffer::BufferingEvent::kNone,
            delay_buffer->Insert(input_block));
  delay_buffer->PrepareCaptureProcessing();
}

// Verifies the SetDelay method.
TEST(RenderDelayBuffer, SetDelay) {
  EchoCanceller3Config config;
  std::unique_ptr<RenderDelayBuffer> delay_buffer(
      RenderDelayBuffer::Create2(config, 1));
  ASSERT_TRUE(delay_buffer->Delay());
  delay_buffer->Reset();
  size_t initial_internal_delay = config.delay.min_echo_path_delay_blocks +
                                  config.delay.api_call_jitter_blocks;
  for (size_t delay = initial_internal_delay;
       delay < initial_internal_delay + 20; ++delay) {
    ASSERT_TRUE(delay_buffer->SetDelay(delay));
    EXPECT_EQ(delay, delay_buffer->Delay());
  }
}

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

// Verifies the check for feasible delay.
// TODO(peah): Re-enable the test once the issue with memory leaks during DEATH
// tests on test bots has been fixed.
TEST(RenderDelayBuffer, DISABLED_WrongDelay) {
  std::unique_ptr<RenderDelayBuffer> delay_buffer(
      RenderDelayBuffer::Create2(EchoCanceller3Config(), 3));
  EXPECT_DEATH(delay_buffer->SetDelay(21), "");
}

// Verifies the check for the number of bands in the inserted blocks.
TEST(RenderDelayBuffer, WrongNumberOfBands) {
  for (auto rate : {16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<RenderDelayBuffer> delay_buffer(RenderDelayBuffer::Create2(
        EchoCanceller3Config(), NumBandsForRate(rate)));
    std::vector<std::vector<float>> block_to_insert(
        NumBandsForRate(rate < 48000 ? rate + 16000 : 16000),
        std::vector<float>(kBlockSize, 0.f));
    EXPECT_DEATH(delay_buffer->Insert(block_to_insert), "");
  }
}

// Verifies the check of the length of the inserted blocks.
TEST(RenderDelayBuffer, WrongBlockLength) {
  for (auto rate : {8000, 16000, 32000, 48000}) {
    SCOPED_TRACE(ProduceDebugText(rate));
    std::unique_ptr<RenderDelayBuffer> delay_buffer(
        RenderDelayBuffer::Create2(EchoCanceller3Config(), 3));
    std::vector<std::vector<float>> block_to_insert(
        NumBandsForRate(rate), std::vector<float>(kBlockSize - 1, 0.f));
    EXPECT_DEATH(delay_buffer->Insert(block_to_insert), "");
  }
}

#endif

}  // namespace webrtc
