/*
 *  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) {
      Reset(config.ep_strength.default_gain);
    }

    void Reset(float default_gain) {
      peak_index = 0;
      gain = default_gain;
      consistent_filter_detector.Reset();
    }

    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_
