/*
 * libjingle
 * Copyright 2013 Google Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *  1. Redistributions of source code must retain the above copyright notice,
 *     this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright notice,
 *     this list of conditions and the following disclaimer in the documentation
 *     and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "talk/app/webrtc/localaudiosource.h"

#include <string>
#include <vector>

#include "talk/app/webrtc/test/fakeconstraints.h"
#include "talk/media/base/fakemediaengine.h"
#include "talk/media/base/fakevideorenderer.h"
#include "webrtc/base/gunit.h"

using webrtc::LocalAudioSource;
using webrtc::MediaConstraintsInterface;
using webrtc::MediaSourceInterface;
using webrtc::PeerConnectionFactoryInterface;

TEST(LocalAudioSourceTest, SetValidOptions) {
  webrtc::FakeConstraints constraints;
  constraints.AddMandatory(
      MediaConstraintsInterface::kGoogEchoCancellation, false);
  constraints.AddOptional(
      MediaConstraintsInterface::kExtendedFilterEchoCancellation, true);
  constraints.AddOptional(MediaConstraintsInterface::kDAEchoCancellation, true);
  constraints.AddOptional(MediaConstraintsInterface::kAutoGainControl, true);
  constraints.AddOptional(
      MediaConstraintsInterface::kExperimentalAutoGainControl, true);
  constraints.AddMandatory(MediaConstraintsInterface::kNoiseSuppression, false);
  constraints.AddOptional(MediaConstraintsInterface::kHighpassFilter, true);
  constraints.AddOptional(MediaConstraintsInterface::kAecDump, true);

  rtc::scoped_refptr<LocalAudioSource> source =
      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
                               &constraints);

  bool value;
  EXPECT_TRUE(source->options().echo_cancellation.Get(&value));
  EXPECT_FALSE(value);
  EXPECT_TRUE(source->options().extended_filter_aec.Get(&value));
  EXPECT_TRUE(value);
  EXPECT_TRUE(source->options().delay_agnostic_aec.Get(&value));
  EXPECT_TRUE(value);
  EXPECT_TRUE(source->options().auto_gain_control.Get(&value));
  EXPECT_TRUE(value);
  EXPECT_TRUE(source->options().experimental_agc.Get(&value));
  EXPECT_TRUE(value);
  EXPECT_TRUE(source->options().noise_suppression.Get(&value));
  EXPECT_FALSE(value);
  EXPECT_TRUE(source->options().highpass_filter.Get(&value));
  EXPECT_TRUE(value);
  EXPECT_TRUE(source->options().aec_dump.Get(&value));
  EXPECT_TRUE(value);
}

TEST(LocalAudioSourceTest, OptionNotSet) {
  webrtc::FakeConstraints constraints;
  rtc::scoped_refptr<LocalAudioSource> source =
      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
                               &constraints);
  bool value;
  EXPECT_FALSE(source->options().highpass_filter.Get(&value));
}

TEST(LocalAudioSourceTest, MandatoryOverridesOptional) {
  webrtc::FakeConstraints constraints;
  constraints.AddMandatory(
      MediaConstraintsInterface::kGoogEchoCancellation, false);
  constraints.AddOptional(
      MediaConstraintsInterface::kGoogEchoCancellation, true);

  rtc::scoped_refptr<LocalAudioSource> source =
      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
                               &constraints);

  bool value;
  EXPECT_TRUE(source->options().echo_cancellation.Get(&value));
  EXPECT_FALSE(value);
}

TEST(LocalAudioSourceTest, InvalidOptional) {
  webrtc::FakeConstraints constraints;
  constraints.AddOptional(MediaConstraintsInterface::kHighpassFilter, false);
  constraints.AddOptional("invalidKey", false);

  rtc::scoped_refptr<LocalAudioSource> source =
      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
                               &constraints);

  EXPECT_EQ(MediaSourceInterface::kLive, source->state());
  bool value;
  EXPECT_TRUE(source->options().highpass_filter.Get(&value));
  EXPECT_FALSE(value);
}

TEST(LocalAudioSourceTest, InvalidMandatory) {
  webrtc::FakeConstraints constraints;
  constraints.AddMandatory(MediaConstraintsInterface::kHighpassFilter, false);
  constraints.AddMandatory("invalidKey", false);

  rtc::scoped_refptr<LocalAudioSource> source =
      LocalAudioSource::Create(PeerConnectionFactoryInterface::Options(),
                               &constraints);

  EXPECT_EQ(MediaSourceInterface::kLive, source->state());
  bool value;
  EXPECT_TRUE(source->options().highpass_filter.Get(&value));
  EXPECT_FALSE(value);
}
