/*
 *  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 "testing/gmock/include/gmock/gmock.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/audio_conference_mixer/interface/audio_conference_mixer.h"
#include "webrtc/modules/audio_conference_mixer/interface/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;

  rtc::scoped_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;

  rtc::scoped_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));

  EXPECT_EQ(0, 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
