/*
 *  Copyright (c) 2014 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 <stdio.h>
#include <iostream>
#include <sstream>
#include <string>

#include "gflags/gflags.h"
#include "webrtc/base/checks.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_audio/channel_buffer.h"
#include "webrtc/common_audio/wav_file.h"
#include "webrtc/modules/audio_processing/include/audio_processing.h"
#include "webrtc/modules/audio_processing/test/audio_file_processor.h"
#include "webrtc/modules/audio_processing/test/protobuf_utils.h"
#include "webrtc/modules/audio_processing/test/test_utils.h"
#include "webrtc/system_wrappers/include/tick_util.h"
#include "webrtc/test/testsupport/trace_to_stderr.h"

DEFINE_string(dump, "", "Name of the aecdump debug file to read from.");
DEFINE_string(i, "", "Name of the capture input stream file to read from.");
DEFINE_string(
    o,
    "out.wav",
    "Name of the output file to write the processed capture stream to.");
DEFINE_int32(out_channels, 1, "Number of output channels.");
DEFINE_int32(out_sample_rate, 48000, "Output sample rate in Hz.");
DEFINE_string(mic_positions, "",
    "Space delimited cartesian coordinates of microphones in meters. "
    "The coordinates of each point are contiguous. "
    "For a two element array: \"x1 y1 z1 x2 y2 z2\"");
DEFINE_double(
    target_angle_degrees,
    90,
    "The azimuth of the target in degrees. Only applies to beamforming.");

DEFINE_bool(aec, false, "Enable echo cancellation.");
DEFINE_bool(agc, false, "Enable automatic gain control.");
DEFINE_bool(hpf, false, "Enable high-pass filtering.");
DEFINE_bool(ns, false, "Enable noise suppression.");
DEFINE_bool(ts, false, "Enable transient suppression.");
DEFINE_bool(bf, false, "Enable beamforming.");
DEFINE_bool(ie, false, "Enable intelligibility enhancer.");
DEFINE_bool(all, false, "Enable all components.");

DEFINE_int32(ns_level, -1, "Noise suppression level [0 - 3].");

DEFINE_bool(perf, false, "Enable performance tests.");

namespace webrtc {
namespace {

const int kChunksPerSecond = 100;
const char kUsage[] =
    "Command-line tool to run audio processing on WAV files. Accepts either\n"
    "an input capture WAV file or protobuf debug dump and writes to an output\n"
    "WAV file.\n"
    "\n"
    "All components are disabled by default. If any bi-directional components\n"
    "are enabled, only debug dump files are permitted.";

}  // namespace

int main(int argc, char* argv[]) {
  google::SetUsageMessage(kUsage);
  google::ParseCommandLineFlags(&argc, &argv, true);

  if (!((FLAGS_i.empty()) ^ (FLAGS_dump.empty()))) {
    fprintf(stderr,
            "An input file must be specified with either -i or -dump.\n");
    return 1;
  }
  if (FLAGS_dump.empty() && (FLAGS_aec || FLAGS_ie)) {
    fprintf(stderr, "-aec and -ie require a -dump file.\n");
    return 1;
  }
  if (FLAGS_ie) {
    fprintf(stderr,
            "FIXME(ajm): The intelligibility enhancer output is not dumped.\n");
    return 1;
  }

  test::TraceToStderr trace_to_stderr(true);
  Config config;
  if (FLAGS_bf || FLAGS_all) {
    if (FLAGS_mic_positions.empty()) {
      fprintf(stderr, "-mic_positions must be specified when -bf is used.\n");
      return 1;
    }
    config.Set<Beamforming>(new Beamforming(
        true, ParseArrayGeometry(FLAGS_mic_positions),
        SphericalPointf(DegreesToRadians(FLAGS_target_angle_degrees), 0.f,
                        1.f)));
  }
  config.Set<ExperimentalNs>(new ExperimentalNs(FLAGS_ts || FLAGS_all));
  config.Set<Intelligibility>(new Intelligibility(FLAGS_ie || FLAGS_all));

  rtc::scoped_ptr<AudioProcessing> ap(AudioProcessing::Create(config));
  RTC_CHECK_EQ(kNoErr, ap->echo_cancellation()->Enable(FLAGS_aec || FLAGS_all));
  RTC_CHECK_EQ(kNoErr, ap->gain_control()->Enable(FLAGS_agc || FLAGS_all));
  RTC_CHECK_EQ(kNoErr, ap->high_pass_filter()->Enable(FLAGS_hpf || FLAGS_all));
  RTC_CHECK_EQ(kNoErr, ap->noise_suppression()->Enable(FLAGS_ns || FLAGS_all));
  if (FLAGS_ns_level != -1) {
    RTC_CHECK_EQ(kNoErr,
                 ap->noise_suppression()->set_level(
                     static_cast<NoiseSuppression::Level>(FLAGS_ns_level)));
  }
  ap->set_stream_key_pressed(FLAGS_ts);

  rtc::scoped_ptr<AudioFileProcessor> processor;
  auto out_file = rtc_make_scoped_ptr(
      new WavWriter(FLAGS_o, FLAGS_out_sample_rate, FLAGS_out_channels));
  std::cout << FLAGS_o << ": " << out_file->FormatAsString() << std::endl;
  if (FLAGS_dump.empty()) {
    auto in_file = rtc_make_scoped_ptr(new WavReader(FLAGS_i));
    std::cout << FLAGS_i << ": " << in_file->FormatAsString() << std::endl;
    processor.reset(
        new WavFileProcessor(ap.Pass(), in_file.Pass(), out_file.Pass()));

  } else {
    processor.reset(new AecDumpFileProcessor(
        ap.Pass(), fopen(FLAGS_dump.c_str(), "rb"), out_file.Pass()));
  }

  int num_chunks = 0;
  while (processor->ProcessChunk()) {
    trace_to_stderr.SetTimeSeconds(num_chunks * 1.f / kChunksPerSecond);
    ++num_chunks;
  }

  if (FLAGS_perf) {
    const auto& proc_time = processor->proc_time();
    int64_t exec_time_us = proc_time.sum.Microseconds();
    printf(
        "\nExecution time: %.3f s, File time: %.2f s\n"
        "Time per chunk (mean, max, min):\n%.0f us, %.0f us, %.0f us\n",
        exec_time_us * 1e-6, num_chunks * 1.f / kChunksPerSecond,
        exec_time_us * 1.f / num_chunks, 1.f * proc_time.max.Microseconds(),
        1.f * proc_time.min.Microseconds());
  }

  return 0;
}

}  // namespace webrtc

int main(int argc, char* argv[]) {
  return webrtc::main(argc, argv);
}
