/*
 *  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/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/common_types.h"
#include "webrtc/modules/audio_coding/codecs/opus/interface/audio_encoder_opus.h"

namespace webrtc {

namespace {
const CodecInst kOpusSettings = {105, "opus", 48000, 960, 1, 32000};
}  // namespace

class AudioEncoderOpusTest : public ::testing::Test {
 protected:
  void CreateCodec(int num_channels) {
    codec_inst_.channels = num_channels;
    encoder_.reset(new AudioEncoderOpus(codec_inst_));
    auto expected_app =
        num_channels == 1 ? AudioEncoderOpus::kVoip : AudioEncoderOpus::kAudio;
    EXPECT_EQ(expected_app, encoder_->application());
  }

  CodecInst codec_inst_ = kOpusSettings;
  rtc::scoped_ptr<AudioEncoderOpus> encoder_;
};

TEST_F(AudioEncoderOpusTest, DefaultApplicationModeMono) {
  CreateCodec(1);
}

TEST_F(AudioEncoderOpusTest, DefaultApplicationModeStereo) {
  CreateCodec(2);
}

TEST_F(AudioEncoderOpusTest, ChangeApplicationMode) {
  CreateCodec(2);
  EXPECT_TRUE(encoder_->SetApplication(AudioEncoder::Application::kSpeech));
  EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
}

TEST_F(AudioEncoderOpusTest, ResetWontChangeApplicationMode) {
  CreateCodec(2);

  // Trigger a reset.
  encoder_->Reset();
  // Verify that the mode is still kAudio.
  EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application());

  // Now change to kVoip.
  EXPECT_TRUE(encoder_->SetApplication(AudioEncoder::Application::kSpeech));
  EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());

  // Trigger a reset again.
  encoder_->Reset();
  // Verify that the mode is still kVoip.
  EXPECT_EQ(AudioEncoderOpus::kVoip, encoder_->application());
}

TEST_F(AudioEncoderOpusTest, ToggleDtx) {
  CreateCodec(2);
  // Enable DTX
  EXPECT_TRUE(encoder_->SetDtx(true));
  // Verify that the mode is still kAudio.
  EXPECT_EQ(AudioEncoderOpus::kAudio, encoder_->application());
  // Turn off DTX.
  EXPECT_TRUE(encoder_->SetDtx(false));
}

TEST_F(AudioEncoderOpusTest, SetBitrate) {
  CreateCodec(1);
  // Constants are replicated from audio_encoder_opus.cc.
  const int kMinBitrateBps = 500;
  const int kMaxBitrateBps = 512000;
  // Set a too low bitrate.
  encoder_->SetTargetBitrate(kMinBitrateBps - 1);
  EXPECT_EQ(kMinBitrateBps, encoder_->GetTargetBitrate());
  // Set a too high bitrate.
  encoder_->SetTargetBitrate(kMaxBitrateBps + 1);
  EXPECT_EQ(kMaxBitrateBps, encoder_->GetTargetBitrate());
  // Set the minimum rate.
  encoder_->SetTargetBitrate(kMinBitrateBps);
  EXPECT_EQ(kMinBitrateBps, encoder_->GetTargetBitrate());
  // Set the maximum rate.
  encoder_->SetTargetBitrate(kMaxBitrateBps);
  EXPECT_EQ(kMaxBitrateBps, encoder_->GetTargetBitrate());
  // Set rates from 1000 up to 32000 bps.
  for (int rate = 1000; rate <= 32000; rate += 1000) {
    encoder_->SetTargetBitrate(rate);
    EXPECT_EQ(rate, encoder_->GetTargetBitrate());
  }
}

namespace {

// Returns a vector with the n evenly-spaced numbers a, a + (b - a)/(n - 1),
// ..., b.
std::vector<double> IntervalSteps(double a, double b, size_t n) {
  DCHECK_GT(n, 1u);
  const double step = (b - a) / (n - 1);
  std::vector<double> points;
  for (size_t i = 0; i < n; ++i)
    points.push_back(a + i * step);
  return points;
}

// Sets the packet loss rate to each number in the vector in turn, and verifies
// that the loss rate as reported by the encoder is |expected_return| for all
// of them.
void TestSetPacketLossRate(AudioEncoderOpus* encoder,
                           const std::vector<double>& losses,
                           double expected_return) {
  for (double loss : losses) {
    encoder->SetProjectedPacketLossRate(loss);
    EXPECT_DOUBLE_EQ(expected_return, encoder->packet_loss_rate());
  }
}

}  // namespace

TEST_F(AudioEncoderOpusTest, PacketLossRateOptimized) {
  CreateCodec(1);
  auto I = [](double a, double b) { return IntervalSteps(a, b, 10); };
  const double eps = 1e-15;

  // Note that the order of the following calls is critical.

  // clang-format off
  TestSetPacketLossRate(encoder_.get(), I(0.00      , 0.01 - eps), 0.00);
  TestSetPacketLossRate(encoder_.get(), I(0.01 + eps, 0.06 - eps), 0.01);
  TestSetPacketLossRate(encoder_.get(), I(0.06 + eps, 0.11 - eps), 0.05);
  TestSetPacketLossRate(encoder_.get(), I(0.11 + eps, 0.22 - eps), 0.10);
  TestSetPacketLossRate(encoder_.get(), I(0.22 + eps, 1.00      ), 0.20);

  TestSetPacketLossRate(encoder_.get(), I(1.00      , 0.18 + eps), 0.20);
  TestSetPacketLossRate(encoder_.get(), I(0.18 - eps, 0.09 + eps), 0.10);
  TestSetPacketLossRate(encoder_.get(), I(0.09 - eps, 0.04 + eps), 0.05);
  TestSetPacketLossRate(encoder_.get(), I(0.04 - eps, 0.01 + eps), 0.01);
  TestSetPacketLossRate(encoder_.get(), I(0.01 - eps, 0.00      ), 0.00);
  // clang-format on
}

}  // namespace webrtc
