/*
 *  Copyright (c) 2012 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.
 */

#ifndef MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
#define MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_

#include <memory>
#include <vector>

#include "modules/audio_processing/include/audio_processing.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/criticalsection.h"

namespace webrtc {

class AudioBuffer;

class EchoCancellationImpl : public EchoCancellation {
 public:
  EchoCancellationImpl(rtc::CriticalSection* crit_render,
                       rtc::CriticalSection* crit_capture);
  ~EchoCancellationImpl() override;

  void ProcessRenderAudio(rtc::ArrayView<const float> packed_render_audio);
  int ProcessCaptureAudio(AudioBuffer* audio, int stream_delay_ms);

  // EchoCancellation implementation.
  bool is_enabled() const override;
  int stream_drift_samples() const override;
  SuppressionLevel suppression_level() const override;
  bool is_drift_compensation_enabled() const override;

  void Initialize(int sample_rate_hz,
                  size_t num_reverse_channels_,
                  size_t num_output_channels_,
                  size_t num_proc_channels_);
  void SetExtraOptions(const webrtc::Config& config);
  bool is_delay_agnostic_enabled() const;
  bool is_extended_filter_enabled() const;
  std::string GetExperimentsDescription();
  bool is_refined_adaptive_filter_enabled() const;

  // Returns the system delay of the first AEC component.
  int GetSystemDelayInSamples() const;

  static void PackRenderAudioBuffer(const AudioBuffer* audio,
                                    size_t num_output_channels,
                                    size_t num_channels,
                                    std::vector<float>* packed_buffer);
  static size_t NumCancellersRequired(size_t num_output_channels,
                                      size_t num_reverse_channels);

  // Enable logging of various AEC statistics.
  int enable_metrics(bool enable) override;

  // Provides various statistics about the AEC.
  int GetMetrics(Metrics* metrics) override;

  // Enable logging of delay metrics.
  int enable_delay_logging(bool enable) override;

  // Provides delay metrics.
  int GetDelayMetrics(int* median,
                      int* std,
                      float* fraction_poor_delays) override;

 private:
  class Canceller;
  struct StreamProperties;

  // EchoCancellation implementation.
  int Enable(bool enable) override;
  int enable_drift_compensation(bool enable) override;
  void set_stream_drift_samples(int drift) override;
  int set_suppression_level(SuppressionLevel level) override;
  bool are_metrics_enabled() const override;
  bool stream_has_echo() const override;
  bool is_delay_logging_enabled() const override;
  int GetDelayMetrics(int* median, int* std) override;

  struct AecCore* aec_core() const override;

  void AllocateRenderQueue();
  int Configure();

  rtc::CriticalSection* const crit_render_ RTC_ACQUIRED_BEFORE(crit_capture_);
  rtc::CriticalSection* const crit_capture_;

  bool enabled_ = false;
  bool drift_compensation_enabled_ RTC_GUARDED_BY(crit_capture_);
  bool metrics_enabled_ RTC_GUARDED_BY(crit_capture_);
  SuppressionLevel suppression_level_ RTC_GUARDED_BY(crit_capture_);
  int stream_drift_samples_ RTC_GUARDED_BY(crit_capture_);
  bool was_stream_drift_set_ RTC_GUARDED_BY(crit_capture_);
  bool stream_has_echo_ RTC_GUARDED_BY(crit_capture_);
  bool delay_logging_enabled_ RTC_GUARDED_BY(crit_capture_);
  bool extended_filter_enabled_ RTC_GUARDED_BY(crit_capture_);
  bool delay_agnostic_enabled_ RTC_GUARDED_BY(crit_capture_);
  bool refined_adaptive_filter_enabled_ RTC_GUARDED_BY(crit_capture_) = false;

  // Only active on Chrome OS devices.
  const bool enforce_zero_stream_delay_ RTC_GUARDED_BY(crit_capture_);

  std::vector<std::unique_ptr<Canceller>> cancellers_;
  std::unique_ptr<StreamProperties> stream_properties_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EchoCancellationImpl);
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_PROCESSING_ECHO_CANCELLATION_IMPL_H_
