/*
 *  Copyright (c) 2018 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 <array>
#include <string>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "common_audio/resampler/push_sinc_resampler.h"
#include "common_audio/wav_file.h"
#include "modules/audio_processing/agc2/cpu_features.h"
#include "modules/audio_processing/agc2/rnn_vad/common.h"
#include "modules/audio_processing/agc2/rnn_vad/features_extraction.h"
#include "modules/audio_processing/agc2/rnn_vad/rnn.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_compare.h"

ABSL_FLAG(std::string, i, "", "Path to the input wav file");
ABSL_FLAG(std::string, f, "", "Path to the output features file");
ABSL_FLAG(std::string, o, "", "Path to the output VAD probabilities file");

namespace webrtc {
namespace rnn_vad {
namespace test {

int main(int argc, char* argv[]) {
  absl::ParseCommandLine(argc, argv);
  rtc::LogMessage::LogToDebug(rtc::LS_INFO);

  // Open wav input file and check properties.
  const std::string input_wav_file = absl::GetFlag(FLAGS_i);
  WavReader wav_reader(input_wav_file);
  if (wav_reader.num_channels() != 1) {
    RTC_LOG(LS_ERROR) << "Only mono wav files are supported";
    return 1;
  }
  if (wav_reader.sample_rate() % 100 != 0) {
    RTC_LOG(LS_ERROR) << "The sample rate rate must allow 10 ms frames.";
    return 1;
  }
  RTC_LOG(LS_INFO) << "Input sample rate: " << wav_reader.sample_rate();

  // Init output files.
  const std::string output_vad_probs_file = absl::GetFlag(FLAGS_o);
  FILE* vad_probs_file = fopen(output_vad_probs_file.c_str(), "wb");
  FILE* features_file = nullptr;
  const std::string output_feature_file = absl::GetFlag(FLAGS_f);
  if (!output_feature_file.empty()) {
    features_file = fopen(output_feature_file.c_str(), "wb");
  }

  // Initialize.
  const int frame_size_10ms =
      rtc::CheckedDivExact(wav_reader.sample_rate(), 100);
  std::vector<float> samples_10ms;
  samples_10ms.resize(frame_size_10ms);
  std::array<float, kFrameSize10ms24kHz> samples_10ms_24kHz;
  PushSincResampler resampler(frame_size_10ms, kFrameSize10ms24kHz);
  const AvailableCpuFeatures cpu_features = GetAvailableCpuFeatures();
  FeaturesExtractor features_extractor(cpu_features);
  std::array<float, kFeatureVectorSize> feature_vector;
  RnnVad rnn_vad(cpu_features);

  // Compute VAD probabilities.
  while (true) {
    // Read frame at the input sample rate.
    const size_t read_samples =
        wav_reader.ReadSamples(frame_size_10ms, samples_10ms.data());
    if (rtc::SafeLt(read_samples, frame_size_10ms)) {
      break;  // EOF.
    }
    // Resample input.
    resampler.Resample(samples_10ms.data(), samples_10ms.size(),
                       samples_10ms_24kHz.data(), samples_10ms_24kHz.size());

    // Extract features and feed the RNN.
    bool is_silence = features_extractor.CheckSilenceComputeFeatures(
        samples_10ms_24kHz, feature_vector);
    float vad_probability =
        rnn_vad.ComputeVadProbability(feature_vector, is_silence);
    // Write voice probability.
    RTC_DCHECK_GE(vad_probability, 0.f);
    RTC_DCHECK_GE(1.f, vad_probability);
    fwrite(&vad_probability, sizeof(float), 1, vad_probs_file);
    // Write features.
    if (features_file) {
      const float float_is_silence = is_silence ? 1.f : 0.f;
      fwrite(&float_is_silence, sizeof(float), 1, features_file);
      if (is_silence) {
        // Do not write uninitialized values.
        feature_vector.fill(0.f);
      }
      fwrite(feature_vector.data(), sizeof(float), kFeatureVectorSize,
             features_file);
    }
  }

  // Close output file(s).
  fclose(vad_probs_file);
  RTC_LOG(LS_INFO) << "VAD probabilities written to " << output_vad_probs_file;
  if (features_file) {
    fclose(features_file);
    RTC_LOG(LS_INFO) << "features written to " << output_feature_file;
  }

  return 0;
}

}  // namespace test
}  // namespace rnn_vad
}  // namespace webrtc

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