/*
 *  Copyright (c) 2016 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 <memory>
#include <utility>

#include "testing/gmock/include/gmock/gmock.h"
#include "webrtc/modules/audio_mixer/audio_mixer_defines.h"
#include "webrtc/modules/audio_mixer/audio_mixer.h"

using testing::_;
using testing::Exactly;
using testing::Invoke;
using testing::Return;

namespace webrtc {

namespace {

constexpr int kDefaultSampleRateHz = 48000;
constexpr int kId = 1;

// Utility function that resets the frame member variables with
// sensible defaults.
void ResetFrame(AudioFrame* frame) {
  frame->id_ = kId;
  frame->sample_rate_hz_ = kDefaultSampleRateHz;
  frame->num_channels_ = 1;

  // Frame duration 10ms.
  frame->samples_per_channel_ = kDefaultSampleRateHz / 100;
  frame->vad_activity_ = AudioFrame::kVadActive;
  frame->speech_type_ = AudioFrame::kNormalSpeech;
}

AudioFrame frame_for_mixing;

}  // namespace

class MockMixerAudioSource : public MixerAudioSource {
 public:
  MockMixerAudioSource()
      : fake_audio_frame_info_(MixerAudioSource::AudioFrameInfo::kNormal) {
    ON_CALL(*this, GetAudioFrameWithMuted(_, _))
        .WillByDefault(
            Invoke(this, &MockMixerAudioSource::FakeAudioFrameWithMuted));
  }

  MOCK_METHOD2(GetAudioFrameWithMuted,
               AudioFrameWithMuted(const int32_t id, int sample_rate_hz));

  AudioFrame* fake_frame() { return &fake_frame_; }
  AudioFrameInfo fake_info() { return fake_audio_frame_info_; }
  void set_fake_info(const AudioFrameInfo audio_frame_info) {
    fake_audio_frame_info_ = audio_frame_info;
  }

 private:
  AudioFrame fake_frame_, fake_output_frame_;
  AudioFrameInfo fake_audio_frame_info_;
  AudioFrameWithMuted FakeAudioFrameWithMuted(const int32_t id,
                                              int sample_rate_hz) {
    fake_output_frame_.CopyFrom(fake_frame_);
    return {
        &fake_output_frame_,  // audio_frame_pointer
        fake_info(),          // audio_frame_info
    };
  }
};

// Creates participants from |frames| and |frame_info| and adds them
// to the mixer. Compares mixed status with |expected_status|
void MixAndCompare(
    const std::vector<AudioFrame>& frames,
    const std::vector<MixerAudioSource::AudioFrameInfo>& frame_info,
    const std::vector<bool>& expected_status) {
  int num_audio_sources = frames.size();
  RTC_DCHECK(frames.size() == frame_info.size());
  RTC_DCHECK(frame_info.size() == expected_status.size());

  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));
  std::vector<MockMixerAudioSource> participants(num_audio_sources);

  for (int i = 0; i < num_audio_sources; i++) {
    participants[i].fake_frame()->CopyFrom(frames[i]);
    participants[i].set_fake_info(frame_info[i]);
  }

  for (int i = 0; i < num_audio_sources; i++) {
    EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
    EXPECT_CALL(participants[i],
                GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
  }

  mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);

  for (int i = 0; i < num_audio_sources; i++) {
    EXPECT_EQ(participants[i].IsMixed(), expected_status[i])
        << "Mixed status of AudioSource #" << i << " wrong.";
  }
}

TEST(AudioMixer, AnonymousAndNamed) {
  // Should not matter even if partipants are more than
  // kMaximumAmountOfMixedAudioSources.
  constexpr int kNamed = AudioMixer::kMaximumAmountOfMixedAudioSources + 1;
  constexpr int kAnonymous = AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource named[kNamed];
  MockMixerAudioSource anonymous[kAnonymous];

  for (int i = 0; i < kNamed; ++i) {
    EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], true));
    EXPECT_TRUE(mixer->MixabilityStatus(named[i]));
  }

  for (int i = 0; i < kAnonymous; ++i) {
    // AudioSource must be registered before turning it into anonymous.
    EXPECT_EQ(-1, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true));
    EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[i], true));
    EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i]));
    EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i]));

    EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], true));
    EXPECT_TRUE(mixer->AnonymousMixabilityStatus(anonymous[i]));

    // Anonymous participants do not show status by MixabilityStatus.
    EXPECT_FALSE(mixer->MixabilityStatus(anonymous[i]));
  }

  for (int i = 0; i < kNamed; ++i) {
    EXPECT_EQ(0, mixer->SetMixabilityStatus(&named[i], false));
    EXPECT_FALSE(mixer->MixabilityStatus(named[i]));
  }

  for (int i = 0; i < kAnonymous - 1; i++) {
    EXPECT_EQ(0, mixer->SetAnonymousMixabilityStatus(&anonymous[i], false));
    EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[i]));

    // SetAnonymousMixabilityStatus(anonymous, false) moves anonymous to the
    // named group.
    EXPECT_TRUE(mixer->MixabilityStatus(anonymous[i]));
  }

  // SetMixabilityStatus(anonymous, false) will remove anonymous from both
  // anonymous and named groups.
  EXPECT_EQ(0, mixer->SetMixabilityStatus(&anonymous[kAnonymous - 1], false));
  EXPECT_FALSE(mixer->AnonymousMixabilityStatus(anonymous[kAnonymous - 1]));
  EXPECT_FALSE(mixer->MixabilityStatus(anonymous[kAnonymous - 1]));
}

TEST(AudioMixer, LargestEnergyVadActiveMixed) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 3;

  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource participants[kAudioSources];

  for (int i = 0; i < kAudioSources; ++i) {
    ResetFrame(participants[i].fake_frame());

    // We set the 80-th sample value since the first 80 samples may be
    // modified by a ramped-in window.
    participants[i].fake_frame()->data_[80] = i;

    EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
    EXPECT_CALL(participants[i], GetAudioFrameWithMuted(_, _))
        .Times(Exactly(1));
  }

  // Last participant gives audio frame with passive VAD, although it has the
  // largest energy.
  participants[kAudioSources - 1].fake_frame()->vad_activity_ =
      AudioFrame::kVadPassive;

  AudioFrame audio_frame;
  mixer->Mix(kDefaultSampleRateHz,
             1,  // number of channels
             &audio_frame);

  for (int i = 0; i < kAudioSources; ++i) {
    bool is_mixed = participants[i].IsMixed();
    if (i == kAudioSources - 1 ||
        i < kAudioSources - 1 - AudioMixer::kMaximumAmountOfMixedAudioSources) {
      EXPECT_FALSE(is_mixed) << "Mixing status of AudioSource #" << i
                             << " wrong.";
    } else {
      EXPECT_TRUE(is_mixed) << "Mixing status of AudioSource #" << i
                            << " wrong.";
    }
  }
}

TEST(AudioMixer, ParticipantSampleRate) {
  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource participant;
  ResetFrame(participant.fake_frame());

  EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
  for (auto frequency : {8000, 16000, 32000, 48000}) {
    EXPECT_CALL(participant, GetAudioFrameWithMuted(_, frequency))
        .Times(Exactly(1));
    mixer->Mix(frequency, 1, &frame_for_mixing);
    EXPECT_EQ(frequency, frame_for_mixing.sample_rate_hz_);
  }
}

TEST(AudioMixer, ParticipantNumberOfChannels) {
  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource participant;
  ResetFrame(participant.fake_frame());

  EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
  for (size_t number_of_channels : {1, 2}) {
    EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
    mixer->Mix(kDefaultSampleRateHz, number_of_channels, &frame_for_mixing);
    EXPECT_EQ(number_of_channels, frame_for_mixing.num_channels_);
  }
}

// Test that the volume is reported as zero when the mixer input
// comprises only zero values.
TEST(AudioMixer, LevelIsZeroWhenMixingZeroes) {
  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource participant;
  ResetFrame(participant.fake_frame());

  EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));
  for (int i = 0; i < 11; i++) {
    EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
    mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
  }

  EXPECT_EQ(0, mixer->GetOutputAudioLevel());
  EXPECT_EQ(0, mixer->GetOutputAudioLevelFullRange());
}

// Test that the reported volume is maximal when the mixer
// input comprises frames with maximal values.
TEST(AudioMixer, LevelIsMaximalWhenMixingMaximalValues) {
  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));

  MockMixerAudioSource participant;
  ResetFrame(participant.fake_frame());

  // Fill participant frame data with maximal sound.
  std::fill(participant.fake_frame()->data_,
            participant.fake_frame()->data_ + kDefaultSampleRateHz / 100,
            std::numeric_limits<int16_t>::max());

  EXPECT_EQ(0, mixer->SetMixabilityStatus(&participant, true));

  // We do >10 iterations, because the audio level indicator only
  // updates once every 10 calls.
  for (int i = 0; i < 11; i++) {
    EXPECT_CALL(participant, GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
    mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);
  }

  // 9 is the highest possible audio level
  EXPECT_EQ(9, mixer->GetOutputAudioLevel());

  // 0x7fff = 32767 is the highest full range audio level.
  EXPECT_EQ(std::numeric_limits<int16_t>::max(),
            mixer->GetOutputAudioLevelFullRange());
}

// Maximal amount of participants are mixed one iteration, then
// another participant with higher energy is added.
TEST(AudioMixer, RampedOutSourcesShouldNotBeMarkedMixed) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  const std::unique_ptr<AudioMixer> mixer(AudioMixer::Create(kId));
  MockMixerAudioSource participants[kAudioSources];

  for (int i = 0; i < kAudioSources; i++) {
    ResetFrame(participants[i].fake_frame());
    // Set the participant audio energy to increase with the index
    // |i|.
    participants[i].fake_frame()->data_[0] = 100 * i;
  }

  // Add all participants but the loudest for mixing.
  for (int i = 0; i < kAudioSources - 1; i++) {
    EXPECT_EQ(0, mixer->SetMixabilityStatus(&participants[i], true));
    EXPECT_CALL(participants[i],
                GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
  }

  // First mixer iteration
  mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);

  // All participants but the loudest should have been mixed.
  for (int i = 0; i < kAudioSources - 1; i++) {
    EXPECT_TRUE(participants[i].IsMixed()) << "Mixed status of AudioSource #"
                                           << i << " wrong.";
  }

  // Add new participant with higher energy.
  EXPECT_EQ(0,
            mixer->SetMixabilityStatus(&participants[kAudioSources - 1], true));
  for (int i = 0; i < kAudioSources; i++) {
    EXPECT_CALL(participants[i],
                GetAudioFrameWithMuted(_, kDefaultSampleRateHz))
        .Times(Exactly(1));
  }

  mixer->Mix(kDefaultSampleRateHz, 1, &frame_for_mixing);

  // The most quiet participant should not have been mixed.
  EXPECT_FALSE(participants[0].IsMixed())
      << "Mixed status of AudioSource #0 wrong.";

  // The loudest participants should have been mixed.
  for (int i = 1; i < kAudioSources; i++) {
    EXPECT_EQ(participants[i].IsMixed(), true)
        << "Mixed status of AudioSource #" << i << " wrong.";
  }
}

TEST(AudioMixer, MutedShouldMixAfterUnmuted) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  std::vector<AudioFrame> frames(kAudioSources);
  for (auto& frame : frames) {
    ResetFrame(&frame);
  }

  std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
      kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
  frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted;
  std::vector<bool> expected_status(kAudioSources, true);
  expected_status[0] = false;

  MixAndCompare(frames, frame_info, expected_status);
}

TEST(AudioMixer, PassiveShouldMixAfterNormal) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  std::vector<AudioFrame> frames(kAudioSources);
  for (auto& frame : frames) {
    ResetFrame(&frame);
  }

  std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
      kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
  frames[0].vad_activity_ = AudioFrame::kVadPassive;
  std::vector<bool> expected_status(kAudioSources, true);
  expected_status[0] = false;

  MixAndCompare(frames, frame_info, expected_status);
}

TEST(AudioMixer, ActiveShouldMixBeforeLoud) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  std::vector<AudioFrame> frames(kAudioSources);
  for (auto& frame : frames) {
    ResetFrame(&frame);
  }

  std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
      kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
  frames[0].vad_activity_ = AudioFrame::kVadPassive;
  std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100,
            std::numeric_limits<int16_t>::max());
  std::vector<bool> expected_status(kAudioSources, true);
  expected_status[0] = false;

  MixAndCompare(frames, frame_info, expected_status);
}

TEST(AudioMixer, UnmutedShouldMixBeforeLoud) {
  constexpr int kAudioSources =
      AudioMixer::kMaximumAmountOfMixedAudioSources + 1;

  std::vector<AudioFrame> frames(kAudioSources);
  for (auto& frame : frames) {
    ResetFrame(&frame);
  }

  std::vector<MixerAudioSource::AudioFrameInfo> frame_info(
      kAudioSources, MixerAudioSource::AudioFrameInfo::kNormal);
  frame_info[0] = MixerAudioSource::AudioFrameInfo::kMuted;
  std::fill(frames[0].data_, frames[0].data_ + kDefaultSampleRateHz / 100,
            std::numeric_limits<int16_t>::max());
  std::vector<bool> expected_status(kAudioSources, true);
  expected_status[0] = false;

  MixAndCompare(frames, frame_info, expected_status);
}
}  // namespace webrtc
