/*
 *  Copyright (c) 2015 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 "testing/gmock/include/gmock/gmock.h"
#include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer.h"
#include "webrtc/modules/audio_conference_mixer/include/audio_conference_mixer_defines.h"

namespace webrtc {

using testing::_;
using testing::AtLeast;
using testing::Invoke;
using testing::Return;

class MockAudioMixerOutputReceiver : public AudioMixerOutputReceiver {
 public:
  MOCK_METHOD4(NewMixedAudio, void(const int32_t id,
                                   const AudioFrame& general_audio_frame,
                                   const AudioFrame** unique_audio_frames,
                                   const uint32_t size));
};

class MockMixerParticipant : public MixerParticipant {
 public:
  MockMixerParticipant() {
    ON_CALL(*this, GetAudioFrame(_, _))
        .WillByDefault(Invoke(this, &MockMixerParticipant::FakeAudioFrame));
  }
  MOCK_METHOD2(GetAudioFrame,
               int32_t(const int32_t id, AudioFrame* audio_frame));
  MOCK_CONST_METHOD1(NeededFrequency, int32_t(const int32_t id));
  AudioFrame* fake_frame() { return &fake_frame_; }

 private:
  AudioFrame fake_frame_;
  int32_t FakeAudioFrame(const int32_t id, AudioFrame* audio_frame) {
    audio_frame->CopyFrom(fake_frame_);
    return 0;
  }
};

TEST(AudioConferenceMixer, AnonymousAndNamed) {
  const int kId = 1;
  // Should not matter even if partipants are more than
  // kMaximumAmountOfMixedParticipants.
  const int kNamed =
      AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1;
  const int kAnonymous =
      AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 1;

  std::unique_ptr<AudioConferenceMixer> mixer(
      AudioConferenceMixer::Create(kId));

  MockMixerParticipant named[kNamed];
  MockMixerParticipant 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) {
    // Participant 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(AudioConferenceMixer, LargestEnergyVadActiveMixed) {
  const int kId = 1;
  const int kParticipants =
      AudioConferenceMixer::kMaximumAmountOfMixedParticipants + 3;
  const int kSampleRateHz = 32000;

  std::unique_ptr<AudioConferenceMixer> mixer(
      AudioConferenceMixer::Create(kId));

  MockAudioMixerOutputReceiver output_receiver;
  EXPECT_EQ(0, mixer->RegisterMixedStreamCallback(&output_receiver));

  MockMixerParticipant participants[kParticipants];

  for (int i = 0; i < kParticipants; ++i) {
    participants[i].fake_frame()->id_ = i;
    participants[i].fake_frame()->sample_rate_hz_ = kSampleRateHz;
    participants[i].fake_frame()->speech_type_ =  AudioFrame::kNormalSpeech;
    participants[i].fake_frame()->vad_activity_ = AudioFrame::kVadActive;
    participants[i].fake_frame()->num_channels_ = 1;

    // Frame duration 10ms.
    participants[i].fake_frame()->samples_per_channel_ = kSampleRateHz / 100;

    // 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], GetAudioFrame(_, _))
        .Times(AtLeast(1));
    EXPECT_CALL(participants[i], NeededFrequency(_))
        .WillRepeatedly(Return(kSampleRateHz));
  }

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

  EXPECT_CALL(output_receiver, NewMixedAudio(_, _, _, _))
      .Times(AtLeast(1));

  mixer->Process();

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

  EXPECT_EQ(0, mixer->UnRegisterMixedStreamCallback());
}

}  // namespace webrtc
