/*
 *  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.
 */

#ifndef MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
#define MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_

#include <stddef.h>

#include <array>
#include <memory>
#include <vector>

#include "api/array_view.h"
#include "api/audio/echo_canceller3_config.h"
#include "modules/audio_processing/aec3/aec3_common.h"
#include "rtc_base/constructor_magic.h"

namespace webrtc {

class ApmDataDumper;
class RenderBuffer;

// Class for analyzing the properties of an adaptive filter.
class FilterAnalyzer {
 public:
  FilterAnalyzer(const EchoCanceller3Config& config,
                 size_t num_capture_channels);
  ~FilterAnalyzer();

  FilterAnalyzer(const FilterAnalyzer&) = delete;
  FilterAnalyzer& operator=(const FilterAnalyzer&) = delete;

  // Resets the analysis.
  void Reset();

  // Updates the estimates with new input data.
  void Update(rtc::ArrayView<const std::vector<float>> filters_time_domain,
              const RenderBuffer& render_buffer,
              bool* any_filter_consistent,
              float* max_echo_path_gain);

  // Returns the delay in blocks for each filter.
  rtc::ArrayView<const int> FilterDelaysBlocks() const {
    return filter_delays_blocks_;
  }

  // Returns the minimum delay of all filters in terms of blocks.
  int MinFilterDelayBlocks() const { return min_filter_delay_blocks_; }

  // Returns the number of blocks for the current used filter.
  int FilterLengthBlocks() const {
    return filter_analysis_states_[0].filter_length_blocks;
  }

  // Returns the preprocessed filter.
  rtc::ArrayView<const std::vector<float>> GetAdjustedFilters() const {
    return h_highpass_;
  }

  // Public for testing purposes only.
  void SetRegionToAnalyze(size_t filter_size);

 private:
  struct FilterAnalysisState;

  void AnalyzeRegion(
      rtc::ArrayView<const std::vector<float>> filters_time_domain,
      const RenderBuffer& render_buffer);

  void UpdateFilterGain(rtc::ArrayView<const float> filters_time_domain,
                        FilterAnalysisState* st);
  void PreProcessFilters(
      rtc::ArrayView<const std::vector<float>> filters_time_domain);

  void ResetRegion();

  struct FilterRegion {
    size_t start_sample_;
    size_t end_sample_;
  };

  // This class checks whether the shape of the impulse response has been
  // consistent over time.
  class ConsistentFilterDetector {
   public:
    explicit ConsistentFilterDetector(const EchoCanceller3Config& config);
    void Reset();
    bool Detect(rtc::ArrayView<const float> filter_to_analyze,
                const FilterRegion& region,
                rtc::ArrayView<const std::vector<float>> x_block,
                size_t peak_index,
                int delay_blocks);

   private:
    bool significant_peak_;
    float filter_floor_accum_;
    float filter_secondary_peak_;
    size_t filter_floor_low_limit_;
    size_t filter_floor_high_limit_;
    const float active_render_threshold_;
    size_t consistent_estimate_counter_ = 0;
    int consistent_delay_reference_ = -10;
  };

  struct FilterAnalysisState {
    explicit FilterAnalysisState(const EchoCanceller3Config& config)
        : filter_length_blocks(config.filter.refined_initial.length_blocks),
          consistent_filter_detector(config) {}
    float gain;
    size_t peak_index;
    int filter_length_blocks;
    bool consistent_estimate = false;
    ConsistentFilterDetector consistent_filter_detector;
  };

  static int instance_count_;
  std::unique_ptr<ApmDataDumper> data_dumper_;
  const bool bounded_erl_;
  const float default_gain_;
  std::vector<std::vector<float>> h_highpass_;

  size_t blocks_since_reset_ = 0;
  FilterRegion region_;

  std::vector<FilterAnalysisState> filter_analysis_states_;
  std::vector<int> filter_delays_blocks_;

  int min_filter_delay_blocks_ = 0;
};

}  // namespace webrtc

#endif  // MODULES_AUDIO_PROCESSING_AEC3_FILTER_ANALYZER_H_
