/*
 *  Copyright (c) 2016 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 <utility>

#include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/mock/mock_smoothing_filter.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace webrtc {

using ::testing::NiceMock;
using ::testing::Return;
using ::testing::_;

namespace {

// The test uses the following settings:
//
// packet-loss ^   |  |
//             |  A| C|   FEC
//             |    \  \   ON
//             | FEC \ D\_______
//             | OFF B\_________
//             |-----------------> bandwidth
//
// A : (kDisablingBandwidthLow, kDisablingPacketLossAtLowBw)
// B : (kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw)
// C : (kEnablingBandwidthLow, kEnablingPacketLossAtLowBw)
// D : (kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw)

constexpr int kDisablingBandwidthLow = 15000;
constexpr float kDisablingPacketLossAtLowBw = 0.08f;
constexpr int kDisablingBandwidthHigh = 64000;
constexpr float kDisablingPacketLossAtHighBw = 0.01f;
constexpr int kEnablingBandwidthLow = 17000;
constexpr float kEnablingPacketLossAtLowBw = 0.1f;
constexpr int kEnablingBandwidthHigh = 64000;
constexpr float kEnablingPacketLossAtHighBw = 0.05f;

struct FecControllerStates {
  std::unique_ptr<FecController> controller;
  MockSmoothingFilter* packet_loss_smoothed;
};

FecControllerStates CreateFecController(bool initial_fec_enabled) {
  FecControllerStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoothed = mock_smoothing_filter.get();
  EXPECT_CALL(*states.packet_loss_smoothed, Die());
  using Threshold = FecController::Config::Threshold;
  states.controller.reset(new FecController(
      FecController::Config(
          initial_fec_enabled,
          Threshold(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
                    kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
          Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                    kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
          0, nullptr),
      std::move(mock_smoothing_filter)));
  return states;
}

// Checks that the FEC decision given by |states->controller->MakeDecision|
// matches |expected_enable_fec|. It also checks that
// |uplink_packet_loss_fraction| returned by |states->controller->MakeDecision|
// matches |uplink_packet_loss|.
void CheckDecision(FecControllerStates* states,
                   const rtc::Optional<int>& uplink_bandwidth_bps,
                   const rtc::Optional<float>& uplink_packet_loss,
                   bool expected_enable_fec) {
  Controller::NetworkMetrics metrics;
  metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
  metrics.uplink_packet_loss_fraction = uplink_packet_loss;

  if (uplink_packet_loss) {
    // Check that smoothing filter is updated.
    EXPECT_CALL(*states->packet_loss_smoothed, AddSample(*uplink_packet_loss));
  }

  EXPECT_CALL(*states->packet_loss_smoothed, GetAverage())
      .WillRepeatedly(Return(uplink_packet_loss));

  AudioNetworkAdaptor::EncoderRuntimeConfig config;
  states->controller->MakeDecision(metrics, &config);
  EXPECT_EQ(rtc::Optional<bool>(expected_enable_fec), config.enable_fec);

  // Check that |config.uplink_packet_loss_fraction| is properly filled.
  EXPECT_EQ(uplink_packet_loss ? uplink_packet_loss : rtc::Optional<float>(0.0),
            config.uplink_packet_loss_fraction);
}

}  // namespace

TEST(FecControllerTest, OutputInitValueWhenUplinkBandwidthUnknown) {
  constexpr bool kInitialFecEnabled = true;
  auto states = CreateFecController(kInitialFecEnabled);
  // Let uplink packet loss fraction be so low that would cause FEC to turn off
  // if uplink bandwidth was known.
  CheckDecision(&states, rtc::Optional<int>(),
                rtc::Optional<float>(kDisablingPacketLossAtHighBw),
                kInitialFecEnabled);
}

TEST(FecControllerTest, OutputInitValueWhenUplinkPacketLossFractionUnknown) {
  constexpr bool kInitialFecEnabled = true;
  auto states = CreateFecController(kInitialFecEnabled);
  // Let uplink bandwidth be so low that would cause FEC to turn off if uplink
  // bandwidth packet loss fraction was known.
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
                rtc::Optional<float>(), kInitialFecEnabled);
}

TEST(FecControllerTest, EnableFecForHighBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
                rtc::Optional<float>(kEnablingPacketLossAtHighBw), true);
}

TEST(FecControllerTest, MaintainFecOffForHighBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
                rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f),
                false);
}

TEST(FecControllerTest, EnableFecForMediumBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(
      &states,
      rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
      rtc::Optional<float>(
          (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0),
      true);
}

TEST(FecControllerTest, MaintainFecOffForMediumBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(
      &states,
      rtc::Optional<int>((kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2),
      rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.49f +
                           kEnablingPacketLossAtHighBw * 0.51f),
      false);
}

TEST(FecControllerTest, EnableFecForLowBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow),
                rtc::Optional<float>(kEnablingPacketLossAtLowBw), true);
}

TEST(FecControllerTest, MaintainFecOffForLowBandwidth) {
  auto states = CreateFecController(false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow),
                rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f),
                false);
}

TEST(FecControllerTest, MaintainFecOffForVeryLowBandwidth) {
  auto states = CreateFecController(false);
  // Below |kEnablingBandwidthLow|, no packet loss fraction can cause FEC to
  // turn on.
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow - 1),
                rtc::Optional<float>(1.0), false);
}

TEST(FecControllerTest, DisableFecForHighBandwidth) {
  auto states = CreateFecController(true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
                rtc::Optional<float>(kDisablingPacketLossAtHighBw), false);
}

TEST(FecControllerTest, MaintainFecOnForHighBandwidth) {
  auto states = CreateFecController(true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
                rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f),
                true);
}

TEST(FecControllerTest, DisableFecOnMediumBandwidth) {
  auto states = CreateFecController(true);
  CheckDecision(
      &states, rtc::Optional<int>(
                   (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2),
      rtc::Optional<float>(
          (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f),
      false);
}

TEST(FecControllerTest, MaintainFecOnForMediumBandwidth) {
  auto states = CreateFecController(true);
  CheckDecision(
      &states,
      rtc::Optional<int>((kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2),
      rtc::Optional<float>(kDisablingPacketLossAtLowBw * 0.51f +
                           kDisablingPacketLossAtHighBw * 0.49f),
      true);
}

TEST(FecControllerTest, DisableFecForLowBandwidth) {
  auto states = CreateFecController(true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow),
                rtc::Optional<float>(kDisablingPacketLossAtLowBw), false);
}

TEST(FecControllerTest, DisableFecForVeryLowBandwidth) {
  auto states = CreateFecController(true);
  // Below |kEnablingBandwidthLow|, any packet loss fraction can cause FEC to
  // turn off.
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
                rtc::Optional<float>(1.0), false);
}

TEST(FecControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
  // In this test, we let the network metrics to traverse from 1 to 5.
  // packet-loss ^ 1 |  |
  //             |   | 2|
  //             |    \  \ 3
  //             |     \4 \_______
  //             |      \_________
  //             |---------5-------> bandwidth

  auto states = CreateFecController(true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
                rtc::Optional<float>(1.0), false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow),
                rtc::Optional<float>(kEnablingPacketLossAtLowBw * 0.99f),
                false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
                rtc::Optional<float>(kEnablingPacketLossAtHighBw), true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
                rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f),
                true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1),
                rtc::Optional<float>(0.0), false);
}

TEST(FecControllerTest, CheckBehaviorOnSpecialCurves) {
  // We test a special configuration, where the points to define the FEC
  // enabling/disabling curves are placed like the following, otherwise the test
  // is the same as CheckBehaviorOnChangingNetworkMetrics.
  //
  // packet-loss ^   |  |
  //             |   | C|
  //             |   |  |
  //             |   | D|_______
  //             |  A|___B______
  //             |-----------------> bandwidth

  constexpr int kEnablingBandwidthHigh = kEnablingBandwidthLow;
  constexpr float kDisablingPacketLossAtLowBw = kDisablingPacketLossAtHighBw;
  FecControllerStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoothed = mock_smoothing_filter.get();
  EXPECT_CALL(*states.packet_loss_smoothed, Die());
  using Threshold = FecController::Config::Threshold;
  states.controller.reset(new FecController(
      FecController::Config(
          true, Threshold(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
                          kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
          Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                    kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
          0, nullptr),
      std::move(mock_smoothing_filter)));

  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthLow - 1),
                rtc::Optional<float>(1.0), false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthLow),
                rtc::Optional<float>(kEnablingPacketLossAtHighBw * 0.99f),
                false);
  CheckDecision(&states, rtc::Optional<int>(kEnablingBandwidthHigh),
                rtc::Optional<float>(kEnablingPacketLossAtHighBw), true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh),
                rtc::Optional<float>(kDisablingPacketLossAtHighBw * 1.01f),
                true);
  CheckDecision(&states, rtc::Optional<int>(kDisablingBandwidthHigh + 1),
                rtc::Optional<float>(0.0), false);
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(FecControllerDeathTest, InvalidConfig) {
  FecControllerStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoothed = mock_smoothing_filter.get();
  EXPECT_CALL(*states.packet_loss_smoothed, Die());
  using Threshold = FecController::Config::Threshold;
  EXPECT_DEATH(
      states.controller.reset(new FecController(
          FecController::Config(
              true,
              Threshold(kDisablingBandwidthLow - 1, kEnablingPacketLossAtLowBw,
                        kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
              Threshold(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                        kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
              0, nullptr),
          std::move(mock_smoothing_filter))),
      "Check failed");
}
#endif

}  // namespace webrtc
