/*
 *  Copyright (c) 2019 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 <cstddef>
#include <cstdint>
#include <optional>

#include "api/audio/audio_processing.h"
#include "api/audio/echo_canceller3_config.h"
#include "api/environment/environment_factory.h"
#include "modules/audio_processing/aec3/echo_canceller3.h"
#include "modules/audio_processing/audio_buffer.h"
#include "test/fuzzers/fuzz_data_helper.h"

namespace webrtc {
namespace {
using SampleRate = ::webrtc::AudioProcessing::NativeRate;

void PrepareAudioBuffer(int sample_rate_hz,
                        FuzzDataHelper* fuzz_data,
                        AudioBuffer* buffer) {
  float* const* channels = buffer->channels_f();
  for (size_t i = 0; i < buffer->num_channels(); ++i) {
    for (size_t j = 0; j < buffer->num_frames(); ++j) {
      channels[i][j] =
          static_cast<float>(fuzz_data->ReadOrDefaultValue<int16_t>(0));
    }
  }
  if (sample_rate_hz == 32000 || sample_rate_hz == 48000) {
    buffer->SplitIntoFrequencyBands();
  }
}

}  // namespace

void FuzzOneInput(FuzzDataHelper fuzz_data) {
  if (fuzz_data.size() > 200'000) {
    return;
  }

  constexpr int kSampleRates[] = {16000, 32000, 48000};
  const int sample_rate_hz =
      static_cast<size_t>(fuzz_data.SelectOneOf(kSampleRates));

  constexpr int kMaxNumChannels = 9;
  const size_t num_render_channels =
      1 + fuzz_data.ReadOrDefaultValue<uint8_t>(0) % (kMaxNumChannels - 1);
  const size_t num_capture_channels =
      1 + fuzz_data.ReadOrDefaultValue<uint8_t>(0) % (kMaxNumChannels - 1);

  EchoCanceller3 aec3(CreateEnvironment(), EchoCanceller3Config(),
                      /*multichannel_config=*/std::nullopt,
                      /*neural_residual_echo_estimator=*/nullptr,
                      sample_rate_hz, num_render_channels,
                      num_capture_channels);

  AudioBuffer capture_audio(sample_rate_hz, num_capture_channels,
                            sample_rate_hz, num_capture_channels,
                            sample_rate_hz, num_capture_channels);
  AudioBuffer render_audio(sample_rate_hz, num_render_channels, sample_rate_hz,
                           num_render_channels, sample_rate_hz,
                           num_render_channels);

  // Fuzz frames while there is still fuzzer data.
  while (fuzz_data.BytesLeft() > 0) {
    bool is_capture = fuzz_data.ReadOrDefaultValue(true);
    bool level_changed = fuzz_data.ReadOrDefaultValue(true);
    if (is_capture) {
      PrepareAudioBuffer(sample_rate_hz, &fuzz_data, &capture_audio);
      aec3.ProcessCapture(&capture_audio, level_changed);
    } else {
      PrepareAudioBuffer(sample_rate_hz, &fuzz_data, &render_audio);
      aec3.AnalyzeRender(&render_audio);
    }
  }
}
}  // namespace webrtc
