/*
 *  Copyright 2004 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 "pc/currentspeakermonitor.h"
#include "pc/audiomonitor.h"
#include "rtc_base/gunit.h"
#include "rtc_base/thread.h"

namespace cricket {

static const uint32_t kSsrc1 = 1001;
static const uint32_t kSsrc2 = 1002;
static const uint32_t kMinTimeBetweenSwitches = 10;
// Due to limited system clock resolution, the CurrentSpeakerMonitor may
// actually require more or less time between switches than that specified
// in the call to set_min_time_between_switches.  To be safe, we sleep for
// 90 ms more than the min time between switches before checking for a switch.
// I am assuming system clocks do not have a coarser resolution than 90 ms.
static const uint32_t kSleepTimeBetweenSwitches = 100;

class CurrentSpeakerMonitorTest : public testing::Test,
    public sigslot::has_slots<> {
 public:
  CurrentSpeakerMonitorTest() {
    monitor_ = new CurrentSpeakerMonitor(&source_);
    // Shrink the minimum time betweeen switches to 10 ms so we don't have to
    // slow down our tests.
    monitor_->set_min_time_between_switches(kMinTimeBetweenSwitches);
    monitor_->SignalUpdate.connect(this, &CurrentSpeakerMonitorTest::OnUpdate);
    current_speaker_ = 0;
    num_changes_ = 0;
    monitor_->Start();
  }

  ~CurrentSpeakerMonitorTest() {
    delete monitor_;
  }

  void SignalAudioMonitor(const AudioInfo& info) {
    source_.SignalAudioMonitor(&source_, info);
  }

 protected:
  AudioSourceContext source_;
  CurrentSpeakerMonitor* monitor_;
  int num_changes_;
  uint32_t current_speaker_;

  void OnUpdate(CurrentSpeakerMonitor* monitor, uint32_t current_speaker) {
    current_speaker_ = current_speaker;
    num_changes_++;
  }
};

static void InitAudioInfo(AudioInfo* info, int input_level, int output_level) {
  info->input_level = input_level;
  info->output_level = output_level;
}

TEST_F(CurrentSpeakerMonitorTest, NoActiveStreams) {
  AudioInfo info;
  InitAudioInfo(&info, 0, 0);
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, 0U);
  EXPECT_EQ(num_changes_, 0);
}

TEST_F(CurrentSpeakerMonitorTest, MultipleActiveStreams) {
  AudioInfo info;
  InitAudioInfo(&info, 0, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  // No speaker recognized because the initial sample is treated as possibly
  // just noise and disregarded.
  EXPECT_EQ(current_speaker_, 0U);
  EXPECT_EQ(num_changes_, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);
}

// See: https://code.google.com/p/webrtc/issues/detail?id=2409
TEST_F(CurrentSpeakerMonitorTest, DISABLED_RapidSpeakerChange) {
  AudioInfo info;
  InitAudioInfo(&info, 0, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, 0U);
  EXPECT_EQ(num_changes_, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  info.active_streams.push_back(std::make_pair(kSsrc1, 9));
  info.active_streams.push_back(std::make_pair(kSsrc2, 1));
  SignalAudioMonitor(info);

  // We expect no speaker change because of the rapid change.
  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);
}

// Flaky on iOS: webrtc:7057.
#if defined(WEBRTC_IOS)
#define MAYBE_SpeakerChange DISABLED_SpeakerChange
#else
#define MAYBE_SpeakerChange SpeakerChange
#endif
TEST_F(CurrentSpeakerMonitorTest, MAYBE_SpeakerChange) {
  AudioInfo info;
  InitAudioInfo(&info, 0, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, 0U);
  EXPECT_EQ(num_changes_, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  // Wait so the changes don't come so rapidly.
  rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);

  info.active_streams.push_back(std::make_pair(kSsrc1, 9));
  info.active_streams.push_back(std::make_pair(kSsrc2, 1));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc1);
  EXPECT_EQ(num_changes_, 2);
}

TEST_F(CurrentSpeakerMonitorTest, InterwordSilence) {
  AudioInfo info;
  InitAudioInfo(&info, 0, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, 0U);
  EXPECT_EQ(num_changes_, 0);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 7));
  SignalAudioMonitor(info);

  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  // Wait so the changes don't come so rapidly.
  rtc::Thread::SleepMs(kSleepTimeBetweenSwitches);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
  SignalAudioMonitor(info);

  // Current speaker shouldn't have changed because we treat this as an inter-
  // word silence.
  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
  SignalAudioMonitor(info);

  // Current speaker shouldn't have changed because we treat this as an inter-
  // word silence.
  EXPECT_EQ(current_speaker_, kSsrc2);
  EXPECT_EQ(num_changes_, 1);

  info.active_streams.push_back(std::make_pair(kSsrc1, 3));
  info.active_streams.push_back(std::make_pair(kSsrc2, 0));
  SignalAudioMonitor(info);

  // At this point, we should have concluded that SSRC2 stopped speaking.
  EXPECT_EQ(current_speaker_, kSsrc1);
  EXPECT_EQ(num_changes_, 2);
}

}  // namespace cricket
