// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/command_line.h"
#include "base/logging.h"
#include "content/public/common/content_switches.h"
#include "content/renderer/media/mock_media_constraint_factory.h"
#include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h"
#include "content/renderer/media/webrtc_audio_capturer.h"
#include "content/renderer/media/webrtc_local_audio_track.h"
#include "media/audio/audio_parameters.h"
#include "media/base/audio_bus.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/WebKit/public/platform/WebMediaConstraints.h"

using ::testing::_;
using ::testing::AtLeast;

namespace content {

namespace {

class MockCapturerSource : public media::AudioCapturerSource {
 public:
  MockCapturerSource() {}
  MOCK_METHOD3(Initialize, void(const media::AudioParameters& params,
                                CaptureCallback* callback,
                                int session_id));
  MOCK_METHOD0(Start, void());
  MOCK_METHOD0(Stop, void());
  MOCK_METHOD1(SetVolume, void(double volume));
  MOCK_METHOD1(SetAutomaticGainControl, void(bool enable));

 protected:
  virtual ~MockCapturerSource() {}
};

class MockPeerConnectionAudioSink : public PeerConnectionAudioSink {
 public:
  MockPeerConnectionAudioSink() {}
  ~MockPeerConnectionAudioSink() {}
  virtual int OnData(const int16* audio_data, int sample_rate,
                     int number_of_channels, int number_of_frames,
                     const std::vector<int>& channels,
                     int audio_delay_milliseconds, int current_volume,
                     bool need_audio_processing, bool key_pressed) OVERRIDE {
    EXPECT_EQ(sample_rate, params_.sample_rate());
    EXPECT_EQ(number_of_channels, params_.channels());
    EXPECT_EQ(number_of_frames, params_.frames_per_buffer());
    OnDataCallback(audio_data, channels, audio_delay_milliseconds,
                   current_volume, need_audio_processing, key_pressed);
    return 0;
  }
  MOCK_METHOD6(OnDataCallback, void(const int16* audio_data,
                                    const std::vector<int>& channels,
                                    int audio_delay_milliseconds,
                                    int current_volume,
                                    bool need_audio_processing,
                                    bool key_pressed));
  virtual void OnSetFormat(const media::AudioParameters& params) OVERRIDE {
    params_ = params;
    FormatIsSet();
  }
  MOCK_METHOD0(FormatIsSet, void());

 private:
  media::AudioParameters params_;
};

}  // namespace

class WebRtcAudioCapturerTest : public testing::Test {
 protected:
  WebRtcAudioCapturerTest()
#if defined(OS_ANDROID)
      : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 960) {
    // Android works with a buffer size bigger than 20ms.
#else
      : params_(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
                media::CHANNEL_LAYOUT_STEREO, 48000, 16, 128) {
#endif
  }

  void DisableAudioTrackProcessing() {
    CommandLine::ForCurrentProcess()->AppendSwitch(
        switches::kDisableAudioTrackProcessing);
  }

  void VerifyAudioParams(const blink::WebMediaConstraints& constraints,
                         bool need_audio_processing) {
    capturer_ = WebRtcAudioCapturer::CreateCapturer(
        -1, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE,
                             "", "", params_.sample_rate(),
                             params_.channel_layout(),
                             params_.frames_per_buffer()),
        constraints, NULL, NULL);
    capturer_source_ = new MockCapturerSource();
    EXPECT_CALL(*capturer_source_.get(), Initialize(_, capturer_.get(), -1));
    EXPECT_CALL(*capturer_source_.get(), SetAutomaticGainControl(true));
    EXPECT_CALL(*capturer_source_.get(), Start());
    capturer_->SetCapturerSourceForTesting(capturer_source_, params_);

    scoped_refptr<WebRtcLocalAudioTrackAdapter> adapter(
        WebRtcLocalAudioTrackAdapter::Create(std::string(), NULL));
    track_.reset(new WebRtcLocalAudioTrack(adapter, capturer_, NULL));
    track_->Start();

    // Connect a mock sink to the track.
    scoped_ptr<MockPeerConnectionAudioSink> sink(
        new MockPeerConnectionAudioSink());
    track_->AddSink(sink.get());

    int delay_ms = 65;
    bool key_pressed = true;
    double volume = 0.9;

    // MaxVolume() in WebRtcAudioCapturer is hard-coded to return 255, we add
    // 0.5 to do the correct truncation like the production code does.
    int expected_volume_value = volume * capturer_->MaxVolume() + 0.5;
    scoped_ptr<media::AudioBus> audio_bus = media::AudioBus::Create(params_);
    audio_bus->Zero();

    media::AudioCapturerSource::CaptureCallback* callback =
        static_cast<media::AudioCapturerSource::CaptureCallback*>(capturer_);

    // Verify the sink is getting the correct values.
    EXPECT_CALL(*sink, FormatIsSet());
    EXPECT_CALL(*sink,
                OnDataCallback(_, _, delay_ms, expected_volume_value,
                               need_audio_processing, key_pressed))
        .Times(AtLeast(1));
    callback->Capture(audio_bus.get(), delay_ms, volume, key_pressed);

    // Verify the cached values in the capturer fits what we expect.
    base::TimeDelta cached_delay;
    int cached_volume = !expected_volume_value;
    bool cached_key_pressed = !key_pressed;
    capturer_->GetAudioProcessingParams(&cached_delay, &cached_volume,
                                        &cached_key_pressed);
    EXPECT_EQ(cached_delay.InMilliseconds(), delay_ms);
    EXPECT_EQ(cached_volume, expected_volume_value);
    EXPECT_EQ(cached_key_pressed, key_pressed);

    track_->RemoveSink(sink.get());
    EXPECT_CALL(*capturer_source_.get(), Stop());
    capturer_->Stop();
  }

  media::AudioParameters params_;
  scoped_refptr<MockCapturerSource> capturer_source_;
  scoped_refptr<WebRtcAudioCapturer> capturer_;
  scoped_ptr<WebRtcLocalAudioTrack> track_;
};

// Pass the delay value, volume and key_pressed info via capture callback, and
// those values should be correctly stored and passed to the track.
TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithoutAudioProcessing) {
  DisableAudioTrackProcessing();
  // Use constraints with default settings.
  MockMediaConstraintFactory constraint_factory;
  VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), true);
}

TEST_F(WebRtcAudioCapturerTest, VerifyAudioParamsWithAudioProcessing) {
  // Turn off the default constraints to verify that the sink will get packets
  // with a buffer size smaller than 10ms.
  MockMediaConstraintFactory constraint_factory;
  constraint_factory.DisableDefaultAudioConstraints();
  VerifyAudioParams(constraint_factory.CreateWebMediaConstraints(), false);
}

TEST_F(WebRtcAudioCapturerTest, FailToCreateCapturerWithWrongConstraints) {
  MockMediaConstraintFactory constraint_factory;
  const std::string dummy_constraint = "dummy";
  constraint_factory.AddMandatory(dummy_constraint, true);

  scoped_refptr<WebRtcAudioCapturer> capturer(
      WebRtcAudioCapturer::CreateCapturer(
          0, StreamDeviceInfo(MEDIA_DEVICE_AUDIO_CAPTURE,
                               "", "", params_.sample_rate(),
                               params_.channel_layout(),
                               params_.frames_per_buffer()),
          constraint_factory.CreateWebMediaConstraints(), NULL, NULL)
  );
  EXPECT_TRUE(capturer == NULL);
}


}  // namespace content
