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

#include "common_audio/channel_buffer.h"
#include "common_audio/wav_file.h"
#include "modules/audio_processing/beamformer/nonlinear_beamformer.h"
#include "modules/audio_processing/test/test_utils.h"
#include "rtc_base/checks.h"
#include "rtc_base/flags.h"
#include "rtc_base/format_macros.h"

DEFINE_string(i, "", "The name of the input file to read from.");
DEFINE_string(o, "out.wav", "Name of the output file to write to.");
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_bool(help, false, "Prints this message.");

namespace webrtc {
namespace {

const int kChunksPerSecond = 100;
const int kChunkSizeMs = 1000 / kChunksPerSecond;

const char kUsage[] =
    "Command-line tool to run beamforming on WAV files. The signal is passed\n"
    "in as a single band, unlike the audio processing interface which splits\n"
    "signals into multiple bands.\n";

std::vector<Point> ParseArrayGeometry(const std::string& mic_positions) {
  const std::vector<float> values = ParseList<float>(mic_positions);
  const size_t num_mics =
      rtc::CheckedDivExact(values.size(), static_cast<size_t>(3));
  RTC_CHECK_GT(num_mics, 0) << "mic_positions is not large enough.";

  std::vector<Point> result;
  result.reserve(num_mics);
  for (size_t i = 0; i < values.size(); i += 3) {
    result.push_back(Point(values[i + 0], values[i + 1], values[i + 2]));
  }

  return result;
}

std::vector<Point> ParseArrayGeometry(const std::string& mic_positions,
                                      size_t num_mics) {
  std::vector<Point> result = ParseArrayGeometry(mic_positions);
  RTC_CHECK_EQ(result.size(), num_mics)
      << "Could not parse mic_positions or incorrect number of points.";
  return result;
}

}  // namespace

int main(int argc, char* argv[]) {
  if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || FLAG_help ||
      argc != 1) {
    printf("%s", kUsage);
    if (FLAG_help) {
      rtc::FlagList::Print(nullptr, false);
      return 0;
    }
    return 1;
  }

  WavReader in_file(FLAG_i);
  WavWriter out_file(FLAG_o, in_file.sample_rate(), in_file.num_channels());

  const size_t num_mics = in_file.num_channels();
  const std::vector<Point> array_geometry =
      ParseArrayGeometry(FLAG_mic_positions, num_mics);
  RTC_CHECK_EQ(array_geometry.size(), num_mics);

  NonlinearBeamformer bf(array_geometry, array_geometry.size());
  bf.Initialize(kChunkSizeMs, in_file.sample_rate());

  printf("Input file: %s\nChannels: %" PRIuS ", Sample rate: %d Hz\n\n", FLAG_i,
         in_file.num_channels(), in_file.sample_rate());
  printf("Output file: %s\nChannels: %" PRIuS ", Sample rate: %d Hz\n\n",
         FLAG_o, out_file.num_channels(), out_file.sample_rate());

  ChannelBuffer<float> buf(
      rtc::CheckedDivExact(in_file.sample_rate(), kChunksPerSecond),
      in_file.num_channels());

  std::vector<float> interleaved(buf.size());
  while (in_file.ReadSamples(interleaved.size(), &interleaved[0]) ==
         interleaved.size()) {
    FloatS16ToFloat(&interleaved[0], interleaved.size(), &interleaved[0]);
    Deinterleave(&interleaved[0], buf.num_frames(), buf.num_channels(),
                 buf.channels());

    bf.AnalyzeChunk(buf);
    bf.PostFilter(&buf);

    Interleave(buf.channels(), buf.num_frames(), buf.num_channels(),
               &interleaved[0]);
    FloatToFloatS16(&interleaved[0], interleaved.size(), &interleaved[0]);
    out_file.WriteSamples(&interleaved[0], interleaved.size());
  }

  return 0;
}

}  // namespace webrtc

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