/*
 *  Copyright (c) 2016 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_TEST_AUDIO_PROCESSING_SIMULATOR_H_
#define MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_

#include <algorithm>
#include <fstream>
#include <limits>
#include <memory>
#include <string>

#include "api/optional.h"
#include "common_audio/channel_buffer.h"
#include "modules/audio_processing/include/audio_processing.h"
#include "modules/audio_processing/test/fake_recording_device.h"
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/task_queue.h"
#include "rtc_base/timeutils.h"

namespace webrtc {
namespace test {

// Holds all the parameters available for controlling the simulation.
struct SimulationSettings {
  SimulationSettings();
  SimulationSettings(const SimulationSettings&);
  ~SimulationSettings();
  rtc::Optional<int> stream_delay;
  rtc::Optional<int> stream_drift_samples;
  rtc::Optional<int> output_sample_rate_hz;
  rtc::Optional<int> output_num_channels;
  rtc::Optional<int> reverse_output_sample_rate_hz;
  rtc::Optional<int> reverse_output_num_channels;
  rtc::Optional<std::string> microphone_positions;
  int target_angle_degrees = 90;
  rtc::Optional<std::string> output_filename;
  rtc::Optional<std::string> reverse_output_filename;
  rtc::Optional<std::string> input_filename;
  rtc::Optional<std::string> reverse_input_filename;
  rtc::Optional<std::string> artificial_nearend_filename;
  rtc::Optional<bool> use_aec;
  rtc::Optional<bool> use_aecm;
  rtc::Optional<bool> use_ed;  // Residual Echo Detector.
  rtc::Optional<std::string> ed_graph_output_filename;
  rtc::Optional<bool> use_agc;
  rtc::Optional<bool> use_agc2;
  rtc::Optional<bool> use_hpf;
  rtc::Optional<bool> use_ns;
  rtc::Optional<bool> use_ts;
  rtc::Optional<bool> use_bf;
  rtc::Optional<bool> use_ie;
  rtc::Optional<bool> use_vad;
  rtc::Optional<bool> use_le;
  rtc::Optional<bool> use_all;
  rtc::Optional<int> aec_suppression_level;
  rtc::Optional<bool> use_delay_agnostic;
  rtc::Optional<bool> use_extended_filter;
  rtc::Optional<bool> use_drift_compensation;
  rtc::Optional<bool> use_aec3;
  rtc::Optional<bool> use_lc;
  rtc::Optional<bool> use_experimental_agc;
  rtc::Optional<int> aecm_routing_mode;
  rtc::Optional<bool> use_aecm_comfort_noise;
  rtc::Optional<int> agc_mode;
  rtc::Optional<int> agc_target_level;
  rtc::Optional<bool> use_agc_limiter;
  rtc::Optional<int> agc_compression_gain;
  float agc2_fixed_gain_db;
  rtc::Optional<int> vad_likelihood;
  rtc::Optional<int> ns_level;
  rtc::Optional<bool> use_refined_adaptive_filter;
  int initial_mic_level;
  bool simulate_mic_gain = false;
  rtc::Optional<int> simulated_mic_kind;
  bool report_performance = false;
  bool report_bitexactness = false;
  bool use_verbose_logging = false;
  bool discard_all_settings_in_aecdump = true;
  rtc::Optional<std::string> aec_dump_input_filename;
  rtc::Optional<std::string> aec_dump_output_filename;
  bool fixed_interface = false;
  bool store_intermediate_output = false;
  rtc::Optional<std::string> custom_call_order_filename;
};

// Holds a few statistics about a series of TickIntervals.
struct TickIntervalStats {
  TickIntervalStats() : min(std::numeric_limits<int64_t>::max()) {}
  int64_t sum;
  int64_t max;
  int64_t min;
};

// Copies samples present in a ChannelBuffer into an AudioFrame.
void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest);

// Provides common functionality for performing audioprocessing simulations.
class AudioProcessingSimulator {
 public:
  static const int kChunksPerSecond = 1000 / AudioProcessing::kChunkSizeMs;

  explicit AudioProcessingSimulator(const SimulationSettings& settings);
  virtual ~AudioProcessingSimulator();

  // Processes the data in the input.
  virtual void Process() = 0;

  // Returns the execution time of all AudioProcessing calls.
  const TickIntervalStats& proc_time() const { return proc_time_; }

  // Reports whether the processed recording was bitexact.
  bool OutputWasBitexact() { return bitexact_output_; }

  size_t get_num_process_stream_calls() { return num_process_stream_calls_; }
  size_t get_num_reverse_process_stream_calls() {
    return num_reverse_process_stream_calls_;
  }

 protected:
  // RAII class for execution time measurement. Updates the provided
  // TickIntervalStats based on the time between ScopedTimer creation and
  // leaving the enclosing scope.
  class ScopedTimer {
   public:
    explicit ScopedTimer(TickIntervalStats* proc_time)
        : proc_time_(proc_time), start_time_(rtc::TimeNanos()) {}

    ~ScopedTimer();

   private:
    TickIntervalStats* const proc_time_;
    int64_t start_time_;
  };

  TickIntervalStats* mutable_proc_time() { return &proc_time_; }
  void ProcessStream(bool fixed_interface);
  void ProcessReverseStream(bool fixed_interface);
  void CreateAudioProcessor();
  void DestroyAudioProcessor();
  void SetupBuffersConfigsOutputs(int input_sample_rate_hz,
                                  int output_sample_rate_hz,
                                  int reverse_input_sample_rate_hz,
                                  int reverse_output_sample_rate_hz,
                                  int input_num_channels,
                                  int output_num_channels,
                                  int reverse_input_num_channels,
                                  int reverse_output_num_channels);

  const SimulationSettings settings_;
  std::unique_ptr<AudioProcessing> ap_;

  std::unique_ptr<ChannelBuffer<float>> in_buf_;
  std::unique_ptr<ChannelBuffer<float>> out_buf_;
  std::unique_ptr<ChannelBuffer<float>> reverse_in_buf_;
  std::unique_ptr<ChannelBuffer<float>> reverse_out_buf_;
  StreamConfig in_config_;
  StreamConfig out_config_;
  StreamConfig reverse_in_config_;
  StreamConfig reverse_out_config_;
  std::unique_ptr<ChannelBufferWavReader> buffer_reader_;
  std::unique_ptr<ChannelBufferWavReader> reverse_buffer_reader_;
  AudioFrame rev_frame_;
  AudioFrame fwd_frame_;
  bool bitexact_output_ = true;
  int aec_dump_mic_level_ = 0;

 private:
  void SetupOutput();

  size_t num_process_stream_calls_ = 0;
  size_t num_reverse_process_stream_calls_ = 0;
  size_t output_reset_counter_ = 0;
  std::unique_ptr<ChannelBufferWavWriter> buffer_writer_;
  std::unique_ptr<ChannelBufferWavWriter> reverse_buffer_writer_;
  TickIntervalStats proc_time_;
  std::ofstream residual_echo_likelihood_graph_writer_;
  int analog_mic_level_;
  FakeRecordingDevice fake_recording_device_;

  rtc::TaskQueue worker_queue_;

  RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioProcessingSimulator);
};

}  // namespace test
}  // namespace webrtc

#endif  // MODULES_AUDIO_PROCESSING_TEST_AUDIO_PROCESSING_SIMULATOR_H_
