/*
 *  Copyright (c) 2015 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 <stddef.h>  // size_t

#include <memory>
#include <string>
#include <vector>

#include "absl/strings/string_view.h"
#include "api/audio/echo_canceller3_factory.h"
#include "modules/audio_coding/neteq/tools/resample_input_audio_file.h"
#include "modules/audio_processing/aec_dump/aec_dump_factory.h"
#include "modules/audio_processing/test/audio_processing_builder_for_testing.h"
#include "modules/audio_processing/test/debug_dump_replayer.h"
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/task_queue_for_test.h"
#include "test/gtest.h"
#include "test/testsupport/file_utils.h"

namespace webrtc {
namespace test {

namespace {

void MaybeResetBuffer(std::unique_ptr<ChannelBuffer<float>>* buffer,
                      const StreamConfig& config) {
  auto& buffer_ref = *buffer;
  if (!buffer_ref.get() || buffer_ref->num_frames() != config.num_frames() ||
      buffer_ref->num_channels() != config.num_channels()) {
    buffer_ref.reset(
        new ChannelBuffer<float>(config.num_frames(), config.num_channels()));
  }
}

class DebugDumpGenerator {
 public:
  DebugDumpGenerator(absl::string_view input_file_name,
                     int input_rate_hz,
                     int input_channels,
                     absl::string_view reverse_file_name,
                     int reverse_rate_hz,
                     int reverse_channels,
                     absl::string_view dump_file_name,
                     bool enable_pre_amplifier);

  // Constructor that uses default input files.
  explicit DebugDumpGenerator(const AudioProcessing::Config& apm_config);

  ~DebugDumpGenerator();

  // Changes the sample rate of the input audio to the APM.
  void SetInputRate(int rate_hz);

  // Sets if converts stereo input signal to mono by discarding other channels.
  void ForceInputMono(bool mono);

  // Changes the sample rate of the reverse audio to the APM.
  void SetReverseRate(int rate_hz);

  // Sets if converts stereo reverse signal to mono by discarding other
  // channels.
  void ForceReverseMono(bool mono);

  // Sets the required sample rate of the APM output.
  void SetOutputRate(int rate_hz);

  // Sets the required channels of the APM output.
  void SetOutputChannels(int channels);

  std::string dump_file_name() const { return dump_file_name_; }

  void StartRecording();
  void Process(size_t num_blocks);
  void StopRecording();
  AudioProcessing* apm() const { return apm_.get(); }

 private:
  static void ReadAndDeinterleave(ResampleInputAudioFile* audio,
                                  int channels,
                                  const StreamConfig& config,
                                  float* const* buffer);

  // APM input/output settings.
  StreamConfig input_config_;
  StreamConfig reverse_config_;
  StreamConfig output_config_;

  // Input file format.
  const std::string input_file_name_;
  ResampleInputAudioFile input_audio_;
  const int input_file_channels_;

  // Reverse file format.
  const std::string reverse_file_name_;
  ResampleInputAudioFile reverse_audio_;
  const int reverse_file_channels_;

  // Buffer for APM input/output.
  std::unique_ptr<ChannelBuffer<float>> input_;
  std::unique_ptr<ChannelBuffer<float>> reverse_;
  std::unique_ptr<ChannelBuffer<float>> output_;

  bool enable_pre_amplifier_;

  TaskQueueForTest worker_queue_;
  rtc::scoped_refptr<AudioProcessing> apm_;

  const std::string dump_file_name_;
};

DebugDumpGenerator::DebugDumpGenerator(absl::string_view input_file_name,
                                       int input_rate_hz,
                                       int input_channels,
                                       absl::string_view reverse_file_name,
                                       int reverse_rate_hz,
                                       int reverse_channels,
                                       absl::string_view dump_file_name,
                                       bool enable_pre_amplifier)
    : input_config_(input_rate_hz, input_channels),
      reverse_config_(reverse_rate_hz, reverse_channels),
      output_config_(input_rate_hz, input_channels),
      input_audio_(input_file_name, input_rate_hz, input_rate_hz),
      input_file_channels_(input_channels),
      reverse_audio_(reverse_file_name, reverse_rate_hz, reverse_rate_hz),
      reverse_file_channels_(reverse_channels),
      input_(new ChannelBuffer<float>(input_config_.num_frames(),
                                      input_config_.num_channels())),
      reverse_(new ChannelBuffer<float>(reverse_config_.num_frames(),
                                        reverse_config_.num_channels())),
      output_(new ChannelBuffer<float>(output_config_.num_frames(),
                                       output_config_.num_channels())),
      enable_pre_amplifier_(enable_pre_amplifier),
      worker_queue_("debug_dump_generator_worker_queue"),
      dump_file_name_(dump_file_name) {
  AudioProcessingBuilderForTesting apm_builder;
  apm_ = apm_builder.Create();
}

DebugDumpGenerator::DebugDumpGenerator(
    const AudioProcessing::Config& apm_config)
    : DebugDumpGenerator(ResourcePath("near32_stereo", "pcm"),
                         32000,
                         2,
                         ResourcePath("far32_stereo", "pcm"),
                         32000,
                         2,
                         TempFilename(OutputPath(), "debug_aec"),
                         apm_config.pre_amplifier.enabled) {
  apm_->ApplyConfig(apm_config);
}

DebugDumpGenerator::~DebugDumpGenerator() {
  remove(dump_file_name_.c_str());
}

void DebugDumpGenerator::SetInputRate(int rate_hz) {
  input_audio_.set_output_rate_hz(rate_hz);
  input_config_.set_sample_rate_hz(rate_hz);
  MaybeResetBuffer(&input_, input_config_);
}

void DebugDumpGenerator::ForceInputMono(bool mono) {
  const int channels = mono ? 1 : input_file_channels_;
  input_config_.set_num_channels(channels);
  MaybeResetBuffer(&input_, input_config_);
}

void DebugDumpGenerator::SetReverseRate(int rate_hz) {
  reverse_audio_.set_output_rate_hz(rate_hz);
  reverse_config_.set_sample_rate_hz(rate_hz);
  MaybeResetBuffer(&reverse_, reverse_config_);
}

void DebugDumpGenerator::ForceReverseMono(bool mono) {
  const int channels = mono ? 1 : reverse_file_channels_;
  reverse_config_.set_num_channels(channels);
  MaybeResetBuffer(&reverse_, reverse_config_);
}

void DebugDumpGenerator::SetOutputRate(int rate_hz) {
  output_config_.set_sample_rate_hz(rate_hz);
  MaybeResetBuffer(&output_, output_config_);
}

void DebugDumpGenerator::SetOutputChannels(int channels) {
  output_config_.set_num_channels(channels);
  MaybeResetBuffer(&output_, output_config_);
}

void DebugDumpGenerator::StartRecording() {
  apm_->AttachAecDump(
      AecDumpFactory::Create(dump_file_name_.c_str(), -1, &worker_queue_));
}

void DebugDumpGenerator::Process(size_t num_blocks) {
  for (size_t i = 0; i < num_blocks; ++i) {
    ReadAndDeinterleave(&reverse_audio_, reverse_file_channels_,
                        reverse_config_, reverse_->channels());
    ReadAndDeinterleave(&input_audio_, input_file_channels_, input_config_,
                        input_->channels());
    RTC_CHECK_EQ(AudioProcessing::kNoError, apm_->set_stream_delay_ms(100));
    apm_->set_stream_analog_level(100);
    if (enable_pre_amplifier_) {
      apm_->SetRuntimeSetting(
          AudioProcessing::RuntimeSetting::CreateCapturePreGain(1 + i % 10));
    }
    apm_->set_stream_key_pressed(i % 10 == 9);
    RTC_CHECK_EQ(AudioProcessing::kNoError,
                 apm_->ProcessStream(input_->channels(), input_config_,
                                     output_config_, output_->channels()));

    RTC_CHECK_EQ(
        AudioProcessing::kNoError,
        apm_->ProcessReverseStream(reverse_->channels(), reverse_config_,
                                   reverse_config_, reverse_->channels()));
  }
}

void DebugDumpGenerator::StopRecording() {
  apm_->DetachAecDump();
}

void DebugDumpGenerator::ReadAndDeinterleave(ResampleInputAudioFile* audio,
                                             int channels,
                                             const StreamConfig& config,
                                             float* const* buffer) {
  const size_t num_frames = config.num_frames();
  const int out_channels = config.num_channels();

  std::vector<int16_t> signal(channels * num_frames);

  audio->Read(num_frames * channels, &signal[0]);

  // We only allow reducing number of channels by discarding some channels.
  RTC_CHECK_LE(out_channels, channels);
  for (int channel = 0; channel < out_channels; ++channel) {
    for (size_t i = 0; i < num_frames; ++i) {
      buffer[channel][i] = S16ToFloat(signal[i * channels + channel]);
    }
  }
}

}  // namespace

class DebugDumpTest : public ::testing::Test {
 public:
  // VerifyDebugDump replays a debug dump using APM and verifies that the result
  // is bit-exact-identical to the output channel in the dump. This is only
  // guaranteed if the debug dump is started on the first frame.
  void VerifyDebugDump(absl::string_view in_filename);

 private:
  DebugDumpReplayer debug_dump_replayer_;
};

void DebugDumpTest::VerifyDebugDump(absl::string_view in_filename) {
  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(in_filename));

  while (const absl::optional<audioproc::Event> event =
             debug_dump_replayer_.GetNextEvent()) {
    debug_dump_replayer_.RunNextEvent();
    if (event->type() == audioproc::Event::STREAM) {
      const audioproc::Stream* msg = &event->stream();
      const StreamConfig output_config = debug_dump_replayer_.GetOutputConfig();
      const ChannelBuffer<float>* output = debug_dump_replayer_.GetOutput();
      // Check that output of APM is bit-exact to the output in the dump.
      ASSERT_EQ(output_config.num_channels(),
                static_cast<size_t>(msg->output_channel_size()));
      ASSERT_EQ(output_config.num_frames() * sizeof(float),
                msg->output_channel(0).size());
      for (int i = 0; i < msg->output_channel_size(); ++i) {
        ASSERT_EQ(0,
                  memcmp(output->channels()[i], msg->output_channel(i).data(),
                         msg->output_channel(i).size()));
      }
    }
  }
}

TEST_F(DebugDumpTest, SimpleCase) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, ChangeInputFormat) {
  DebugDumpGenerator generator(/*apm_config=*/{});

  generator.StartRecording();
  generator.Process(100);
  generator.SetInputRate(48000);

  generator.ForceInputMono(true);
  // Number of output channel should not be larger than that of input. APM will
  // fail otherwise.
  generator.SetOutputChannels(1);

  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, ChangeReverseFormat) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);
  generator.SetReverseRate(48000);
  generator.ForceReverseMono(true);
  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, ChangeOutputFormat) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);
  generator.SetOutputRate(48000);
  generator.SetOutputChannels(1);
  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, ToggleAec) {
  AudioProcessing::Config apm_config;
  apm_config.echo_canceller.enabled = true;
  DebugDumpGenerator generator(apm_config);
  generator.StartRecording();
  generator.Process(100);

  apm_config.echo_canceller.enabled = false;
  generator.apm()->ApplyConfig(apm_config);

  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringInclusive) {
  AudioProcessing::Config apm_config;
  apm_config.echo_canceller.enabled = true;
  apm_config.gain_controller1.analog_gain_controller.enabled = true;
  apm_config.gain_controller1.analog_gain_controller.startup_min_volume = 0;
  DebugDumpGenerator generator(apm_config);
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();

  DebugDumpReplayer debug_dump_replayer_;

  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));

  while (const absl::optional<audioproc::Event> event =
             debug_dump_replayer_.GetNextEvent()) {
    debug_dump_replayer_.RunNextEvent();
    if (event->type() == audioproc::Event::CONFIG) {
      const audioproc::Config* msg = &event->config();
      ASSERT_TRUE(msg->has_experiments_description());
      EXPECT_PRED_FORMAT2(::testing::IsSubstring, "EchoController",
                          msg->experiments_description().c_str());
    }
  }
}

TEST_F(DebugDumpTest, VerifyCombinedExperimentalStringExclusive) {
  AudioProcessing::Config apm_config;
  apm_config.echo_canceller.enabled = true;
  DebugDumpGenerator generator(apm_config);
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();

  DebugDumpReplayer debug_dump_replayer_;

  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));

  while (const absl::optional<audioproc::Event> event =
             debug_dump_replayer_.GetNextEvent()) {
    debug_dump_replayer_.RunNextEvent();
    if (event->type() == audioproc::Event::CONFIG) {
      const audioproc::Config* msg = &event->config();
      ASSERT_TRUE(msg->has_experiments_description());
      EXPECT_PRED_FORMAT2(::testing::IsNotSubstring,
                          "AgcClippingLevelExperiment",
                          msg->experiments_description().c_str());
    }
  }
}

TEST_F(DebugDumpTest, VerifyAec3ExperimentalString) {
  AudioProcessing::Config apm_config;
  apm_config.echo_canceller.enabled = true;
  DebugDumpGenerator generator(apm_config);
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();

  DebugDumpReplayer debug_dump_replayer_;

  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));

  while (const absl::optional<audioproc::Event> event =
             debug_dump_replayer_.GetNextEvent()) {
    debug_dump_replayer_.RunNextEvent();
    if (event->type() == audioproc::Event::CONFIG) {
      const audioproc::Config* msg = &event->config();
      ASSERT_TRUE(msg->has_experiments_description());
      EXPECT_PRED_FORMAT2(::testing::IsSubstring, "EchoController",
                          msg->experiments_description().c_str());
    }
  }
}

TEST_F(DebugDumpTest, VerifyEmptyExperimentalString) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();

  DebugDumpReplayer debug_dump_replayer_;

  ASSERT_TRUE(debug_dump_replayer_.SetDumpFile(generator.dump_file_name()));

  while (const absl::optional<audioproc::Event> event =
             debug_dump_replayer_.GetNextEvent()) {
    debug_dump_replayer_.RunNextEvent();
    if (event->type() == audioproc::Event::CONFIG) {
      const audioproc::Config* msg = &event->config();
      ASSERT_TRUE(msg->has_experiments_description());
      EXPECT_EQ(0u, msg->experiments_description().size());
    }
  }
}

// AGC is not supported on Android or iOS.
#if defined(WEBRTC_ANDROID) || defined(WEBRTC_IOS)
#define MAYBE_ToggleAgc DISABLED_ToggleAgc
#else
#define MAYBE_ToggleAgc ToggleAgc
#endif
TEST_F(DebugDumpTest, MAYBE_ToggleAgc) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);

  AudioProcessing::Config apm_config = generator.apm()->GetConfig();
  apm_config.gain_controller1.enabled = !apm_config.gain_controller1.enabled;
  generator.apm()->ApplyConfig(apm_config);

  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, ToggleNs) {
  DebugDumpGenerator generator(/*apm_config=*/{});
  generator.StartRecording();
  generator.Process(100);

  AudioProcessing::Config apm_config = generator.apm()->GetConfig();
  apm_config.noise_suppression.enabled = !apm_config.noise_suppression.enabled;
  generator.apm()->ApplyConfig(apm_config);

  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, TransientSuppressionOn) {
  DebugDumpGenerator generator(/*apm_config=*/{});

  AudioProcessing::Config apm_config = generator.apm()->GetConfig();
  apm_config.transient_suppression.enabled = true;
  generator.apm()->ApplyConfig(apm_config);

  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

TEST_F(DebugDumpTest, PreAmplifierIsOn) {
  AudioProcessing::Config apm_config;
  apm_config.pre_amplifier.enabled = true;
  DebugDumpGenerator generator(apm_config);
  generator.StartRecording();
  generator.Process(100);
  generator.StopRecording();
  VerifyDebugDump(generator.dump_file_name());
}

}  // namespace test
}  // namespace webrtc
