/*
 *  Copyright (c) 2017 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 "modules/audio_processing/test/conversational_speech/simulator.h"

#include <math.h>

#include <algorithm>
#include <set>
#include <utility>
#include <vector>

#include "api/array_view.h"
#include "common_audio/wav_file.h"
#include "modules/audio_processing/test/conversational_speech/wavreader_interface.h"
#include "rtc_base/constructormagic.h"
#include "rtc_base/logging.h"
#include "rtc_base/numerics/safe_conversions.h"
#include "rtc_base/pathutils.h"
#include "rtc_base/ptr_util.h"

namespace webrtc {
namespace test {
namespace {

using conversational_speech::MultiEndCall;
using conversational_speech::SpeakerOutputFilePaths;
using conversational_speech::WavReaderInterface;

// Combines output path and speaker names to define the output file paths for
// the near-end and far=end audio tracks.
std::unique_ptr<std::map<std::string, SpeakerOutputFilePaths>>
    InitSpeakerOutputFilePaths(const std::set<std::string>& speaker_names,
                               const std::string& output_path) {
  // Create map.
  auto speaker_output_file_paths_map = rtc::MakeUnique<
      std::map<std::string, SpeakerOutputFilePaths>>();

  // Add near-end and far-end output paths into the map.
  for (const auto& speaker_name : speaker_names) {
    const rtc::Pathname near_end_path(
        output_path, "s_" + speaker_name + "-near_end.wav");
    RTC_LOG(LS_VERBOSE) << "The near-end audio track will be created in "
                        << near_end_path.pathname() << ".";

    const rtc::Pathname far_end_path(
        output_path, "s_" + speaker_name + "-far_end.wav");
    RTC_LOG(LS_VERBOSE) << "The far-end audio track will be created in "
                        << far_end_path.pathname() << ".";

    // Add to map.
    speaker_output_file_paths_map->emplace(
        std::piecewise_construct,
        std::forward_as_tuple(speaker_name),
        std::forward_as_tuple(near_end_path.pathname(),
                              far_end_path.pathname()));
  }

  return speaker_output_file_paths_map;
}

// Class that provides one WavWriter for the near-end and one for the far-end
// output track of a speaker.
class SpeakerWavWriters {
 public:
  SpeakerWavWriters(
      const SpeakerOutputFilePaths& output_file_paths, int sample_rate)
          : near_end_wav_writer_(output_file_paths.near_end, sample_rate, 1u),
            far_end_wav_writer_(output_file_paths.far_end, sample_rate, 1u) {}
  WavWriter* near_end_wav_writer() {
    return &near_end_wav_writer_;
  }
  WavWriter* far_end_wav_writer() {
    return &far_end_wav_writer_;
  }
 private:
  WavWriter near_end_wav_writer_;
  WavWriter far_end_wav_writer_;
};

// Initializes one WavWriter instance for each speaker and both the near-end and
// far-end output tracks.
std::unique_ptr<std::map<std::string, SpeakerWavWriters>>
    InitSpeakersWavWriters(const std::map<std::string, SpeakerOutputFilePaths>&
                           speaker_output_file_paths, int sample_rate) {
  // Create map.
  auto speaker_wav_writers_map = rtc::MakeUnique<
      std::map<std::string, SpeakerWavWriters>>();

  // Add SpeakerWavWriters instance into the map.
  for (auto it = speaker_output_file_paths.begin();
      it != speaker_output_file_paths.end(); ++it) {
    speaker_wav_writers_map->emplace(
        std::piecewise_construct,
        std::forward_as_tuple(it->first),
        std::forward_as_tuple(it->second, sample_rate));
  }

  return speaker_wav_writers_map;
}

// Reads all the samples for each audio track.
std::unique_ptr<std::map<std::string, std::vector<int16_t>>> PreloadAudioTracks(
    const std::map<std::string, std::unique_ptr<WavReaderInterface>>&
        audiotrack_readers) {
  // Create map.
  auto audiotracks_map = rtc::MakeUnique<
      std::map<std::string, std::vector<int16_t>>>();

  // Add audio track vectors.
  for (auto it = audiotrack_readers.begin(); it != audiotrack_readers.end();
      ++it) {
    // Add map entry.
    audiotracks_map->emplace(
        std::piecewise_construct,
        std::forward_as_tuple(it->first),
        std::forward_as_tuple(it->second->NumSamples()));

    // Read samples.
    it->second->ReadInt16Samples(audiotracks_map->at(it->first));
  }

  return audiotracks_map;
}

// Writes all the values in |source_samples| via |wav_writer|. If the number of
// previously written samples in |wav_writer| is less than |interval_begin|, it
// adds zeros as left padding. The padding corresponds to intervals during which
// a speaker is not active.
void PadLeftWriteChunk(rtc::ArrayView<const int16_t> source_samples,
                       size_t interval_begin, WavWriter* wav_writer) {
  // Add left padding.
  RTC_CHECK(wav_writer);
  RTC_CHECK_GE(interval_begin, wav_writer->num_samples());
  size_t padding_size = interval_begin - wav_writer->num_samples();
  if (padding_size != 0) {
    const std::vector<int16_t> padding(padding_size, 0);
    wav_writer->WriteSamples(padding.data(), padding_size);
  }

  // Write source samples.
  wav_writer->WriteSamples(source_samples.data(), source_samples.size());
}

// Appends zeros via |wav_writer|. The number of zeros is always non-negative
// and equal to the difference between the previously written samples and
// |pad_samples|.
void PadRightWrite(WavWriter* wav_writer, size_t pad_samples) {
  RTC_CHECK(wav_writer);
  RTC_CHECK_GE(pad_samples, wav_writer->num_samples());
  size_t padding_size = pad_samples - wav_writer->num_samples();
  if (padding_size != 0) {
    const std::vector<int16_t> padding(padding_size, 0);
    wav_writer->WriteSamples(padding.data(), padding_size);
  }
}

void ScaleSignal(rtc::ArrayView<const int16_t> source_samples,
                 int gain,
                 rtc::ArrayView<int16_t> output_samples) {
  const float gain_linear = pow(10.0, gain / 20.0);
  RTC_DCHECK_EQ(source_samples.size(), output_samples.size());
  std::transform(source_samples.begin(), source_samples.end(),
                 output_samples.begin(), [gain_linear](int16_t x) -> int16_t {
                   return rtc::saturated_cast<int16_t>(x * gain_linear);
                 });
}

}  // namespace

namespace conversational_speech {

std::unique_ptr<std::map<std::string, SpeakerOutputFilePaths>> Simulate(
    const MultiEndCall& multiend_call, const std::string& output_path) {
  // Set output file paths and initialize wav writers.
  const auto& speaker_names = multiend_call.speaker_names();
  auto speaker_output_file_paths = InitSpeakerOutputFilePaths(
      speaker_names, output_path);
  auto speakers_wav_writers = InitSpeakersWavWriters(
      *speaker_output_file_paths, multiend_call.sample_rate());

  // Preload all the input audio tracks.
  const auto& audiotrack_readers = multiend_call.audiotrack_readers();
  auto audiotracks = PreloadAudioTracks(audiotrack_readers);

  // TODO(alessiob): When speaker_names.size() == 2, near-end and far-end
  // across the 2 speakers are symmetric; hence, the code below could be
  // replaced by only creating the near-end or the far-end. However, this would
  // require to split the unit tests and document the behavior in README.md.
  // In practice, it should not be an issue since the files are not expected to
  // be signinificant.

  // Write near-end and far-end output tracks.
  for (const auto& speaking_turn : multiend_call.speaking_turns()) {
    const std::string& active_speaker_name = speaking_turn.speaker_name;
    const auto source_audiotrack =
        audiotracks->at(speaking_turn.audiotrack_file_name);
    std::vector<int16_t> scaled_audiotrack(source_audiotrack.size());
    ScaleSignal(source_audiotrack, speaking_turn.gain, scaled_audiotrack);

    // Write active speaker's chunk to active speaker's near-end.
    PadLeftWriteChunk(
        scaled_audiotrack, speaking_turn.begin,
        speakers_wav_writers->at(active_speaker_name).near_end_wav_writer());

    // Write active speaker's chunk to other participants' far-ends.
    for (const std::string& speaker_name : speaker_names) {
      if (speaker_name == active_speaker_name)
        continue;
      PadLeftWriteChunk(
          scaled_audiotrack, speaking_turn.begin,
          speakers_wav_writers->at(speaker_name).far_end_wav_writer());
    }
  }

  // Finalize all the output tracks with right padding.
  // This is required to make all the output tracks duration equal.
  size_t duration_samples = multiend_call.total_duration_samples();
  for (const std::string& speaker_name : speaker_names) {
    PadRightWrite(speakers_wav_writers->at(speaker_name).near_end_wav_writer(),
                  duration_samples);
    PadRightWrite(speakers_wav_writers->at(speaker_name).far_end_wav_writer(),
                  duration_samples);
  }

  return speaker_output_file_paths;
}

}  // namespace conversational_speech
}  // namespace test
}  // namespace webrtc
