/*
 *  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 "webrtc/test/fuzzers/audio_processing_fuzzer.h"

#include <algorithm>
#include <array>
#include <cmath>

#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/include/module_common_types.h"
#include "webrtc/rtc_base/checks.h"

namespace webrtc {
namespace {
size_t ByteToNativeRate(uint8_t data) {
  using Rate = AudioProcessing::NativeRate;
  switch (data % 4) {
    case 0:
    // Breaks AEC3.
    // return static_cast<size_t>(Rate::kSampleRate8kHz);
    case 1:
      return static_cast<size_t>(Rate::kSampleRate16kHz);
    case 2:
      return static_cast<size_t>(Rate::kSampleRate32kHz);
    default:
      return static_cast<size_t>(Rate::kSampleRate48kHz);
  }
}

template <class T>
bool ParseSequence(size_t size,
                   const uint8_t** data,
                   size_t* remaining_size,
                   T* result_data) {
  const size_t data_size_bytes = sizeof(T) * size;
  if (data_size_bytes > *remaining_size) {
    return false;
  }

  std::copy(*data, *data + data_size_bytes,
            reinterpret_cast<uint8_t*>(result_data));

  *data += data_size_bytes;
  *remaining_size -= data_size_bytes;
  return true;
}

void FuzzAudioProcessing(const uint8_t* data,
                         size_t size,
                         bool is_float,
                         AudioProcessing* apm) {
  AudioFrame fixed_frame;
  std::array<float, 480> float_frame{};
  float* const first_channel = &float_frame[0];

  while (size > 0) {
    // Decide input/output rate for this iteration.
    const auto input_rate_byte = ParseByte(&data, &size);
    const auto output_rate_byte = ParseByte(&data, &size);
    if (!input_rate_byte || !output_rate_byte) {
      return;
    }
    const auto input_rate_hz = ByteToNativeRate(*input_rate_byte);
    const auto output_rate_hz = ByteToNativeRate(*output_rate_byte);

    const size_t samples_per_input_channel =
        rtc::CheckedDivExact(input_rate_hz, 100ul);
    fixed_frame.samples_per_channel_ = samples_per_input_channel;
    fixed_frame.sample_rate_hz_ = input_rate_hz;

    // Two channels breaks AEC3.
    fixed_frame.num_channels_ = 1;

    // Fill the arrays with audio samples from the data.
    if (is_float) {
      if (!ParseSequence(samples_per_input_channel, &data, &size,
                         &float_frame[0])) {
        return;
      }
    } else if (!ParseSequence(samples_per_input_channel, &data, &size,
                              fixed_frame.mutable_data())) {
      return;
    }

    // Filter obviously wrong values like inf/nan and values that will
    // lead to inf/nan in calculations. 1e6 leads to DCHECKS failing.
    for (auto& x : float_frame) {
      if (!std::isnormal(x) || std::abs(x) > 1e5) {
        x = 0;
      }
    }

    // Make the APM call depending on capture/render mode and float /
    // fix interface.
    const auto is_capture = ParseBool(&data, &size);
    if (!is_capture) {
      return;
    }
    if (*is_capture) {
      auto apm_return_code =
          is_float ? (apm->ProcessStream(
                         &first_channel, StreamConfig(input_rate_hz, 1),
                         StreamConfig(output_rate_hz, 1), &first_channel))
                   : (apm->ProcessStream(&fixed_frame));
      RTC_DCHECK_NE(apm_return_code, AudioProcessing::kBadDataLengthError);
    } else {
      auto apm_return_code =
          is_float ? (apm->ProcessReverseStream(
                         &first_channel, StreamConfig(input_rate_hz, 1),
                         StreamConfig(output_rate_hz, 1), &first_channel))
                   : (apm->ProcessReverseStream(&fixed_frame));
      RTC_DCHECK_NE(apm_return_code, AudioProcessing::kBadDataLengthError);
    }
  }
}

}  // namespace

rtc::Optional<bool> ParseBool(const uint8_t** data, size_t* remaining_size) {
  if (1 > *remaining_size) {
    return rtc::Optional<bool>();
  }
  auto res = rtc::Optional<bool>((**data) % 2);
  *data += 1;
  *remaining_size -= 1;
  return res;
}

rtc::Optional<uint8_t> ParseByte(const uint8_t** data, size_t* remaining_size) {
  if (1 > *remaining_size) {
    return rtc::Optional<uint8_t>();
  }
  auto res = rtc::Optional<uint8_t>((**data));
  *data += 1;
  *remaining_size -= 1;
  return res;
}

void FuzzAudioProcessing(const uint8_t* data,
                         size_t size,
                         std::unique_ptr<AudioProcessing> apm) {
  const auto is_float = ParseBool(&data, &size);
  if (!is_float) {
    return;
  }

  FuzzAudioProcessing(data, size, *is_float, apm.get());
}
}  // namespace webrtc
