/*
 *  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/common_audio/mocks/mock_smoothing_filter.h"
#include "webrtc/modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
#include "webrtc/test/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;

constexpr float kEpsilon = 1e-5f;

struct FecControllerPlrBasedTestStates {
  std::unique_ptr<FecControllerPlrBased> controller;
  MockSmoothingFilter* packet_loss_smoother;
};

FecControllerPlrBasedTestStates CreateFecControllerPlrBased(
    bool initial_fec_enabled,
    const ThresholdCurve& enabling_curve,
    const ThresholdCurve& disabling_curve) {
  FecControllerPlrBasedTestStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoother = mock_smoothing_filter.get();
  states.controller.reset(new FecControllerPlrBased(
      FecControllerPlrBased::Config(initial_fec_enabled, enabling_curve,
                                    disabling_curve, 0),
      std::move(mock_smoothing_filter)));
  return states;
}

FecControllerPlrBasedTestStates CreateFecControllerPlrBased(
    bool initial_fec_enabled) {
  return CreateFecControllerPlrBased(
      initial_fec_enabled,
      ThresholdCurve(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
                     kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
      ThresholdCurve(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                     kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw));
}

void UpdateNetworkMetrics(FecControllerPlrBasedTestStates* states,
                          const rtc::Optional<int>& uplink_bandwidth_bps,
                          const rtc::Optional<float>& uplink_packet_loss) {
  // UpdateNetworkMetrics can accept multiple network metric updates at once.
  // However, currently, the most used case is to update one metric at a time.
  // To reflect this fact, we separate the calls.
  if (uplink_bandwidth_bps) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_bandwidth_bps = uplink_bandwidth_bps;
    states->controller->UpdateNetworkMetrics(network_metrics);
  }
  if (uplink_packet_loss) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_packet_loss_fraction = uplink_packet_loss;
    EXPECT_CALL(*states->packet_loss_smoother, AddSample(*uplink_packet_loss));
    states->controller->UpdateNetworkMetrics(network_metrics);
    // This is called during CheckDecision().
    EXPECT_CALL(*states->packet_loss_smoother, GetAverage())
        .WillOnce(Return(rtc::Optional<float>(*uplink_packet_loss)));
  }
}

void UpdateNetworkMetrics(FecControllerPlrBasedTestStates* states,
                          int uplink_bandwidth_bps,
                          float uplink_packet_loss) {
  UpdateNetworkMetrics(states, rtc::Optional<int>(uplink_bandwidth_bps),
                       rtc::Optional<float>(uplink_packet_loss));
}

// Checks that the FEC decision and |uplink_packet_loss_fraction| given by
// |states->controller->MakeDecision| matches |expected_enable_fec| and
// |expected_uplink_packet_loss_fraction|, respectively.
void CheckDecision(FecControllerPlrBasedTestStates* states,
                   bool expected_enable_fec,
                   float expected_uplink_packet_loss_fraction) {
  AudioEncoderRuntimeConfig config;
  states->controller->MakeDecision(&config);
  EXPECT_EQ(rtc::Optional<bool>(expected_enable_fec), config.enable_fec);
  EXPECT_EQ(rtc::Optional<float>(expected_uplink_packet_loss_fraction),
            config.uplink_packet_loss_fraction);
}

}  // namespace

TEST(FecControllerPlrBasedTest, OutputInitValueBeforeAnyInputsAreReceived) {
  for (bool initial_fec_enabled : {false, true}) {
    auto states = CreateFecControllerPlrBased(initial_fec_enabled);
    CheckDecision(&states, initial_fec_enabled, 0);
  }
}

TEST(FecControllerPlrBasedTest, OutputInitValueWhenUplinkBandwidthUnknown) {
  // Regardless of the initial FEC state and the packet-loss rate,
  // the initial FEC state is maintained as long as the BWE is unknown.
  for (bool initial_fec_enabled : {false, true}) {
    for (float packet_loss :
         {kDisablingPacketLossAtLowBw - kEpsilon, kDisablingPacketLossAtLowBw,
          kDisablingPacketLossAtLowBw + kEpsilon,
          kEnablingPacketLossAtLowBw - kEpsilon, kEnablingPacketLossAtLowBw,
          kEnablingPacketLossAtLowBw + kEpsilon}) {
      auto states = CreateFecControllerPlrBased(initial_fec_enabled);
      UpdateNetworkMetrics(&states, rtc::Optional<int>(),
                           rtc::Optional<float>(packet_loss));
      CheckDecision(&states, initial_fec_enabled, packet_loss);
    }
  }
}

TEST(FecControllerPlrBasedTest,
     OutputInitValueWhenUplinkPacketLossFractionUnknown) {
  // Regardless of the initial FEC state and the BWE, the initial FEC state
  // is maintained as long as the packet-loss rate is unknown.
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {kDisablingBandwidthLow - 1, kDisablingBandwidthLow,
                          kDisablingBandwidthLow + 1, kEnablingBandwidthLow - 1,
                          kEnablingBandwidthLow, kEnablingBandwidthLow + 1}) {
      auto states = CreateFecControllerPlrBased(initial_fec_enabled);
      UpdateNetworkMetrics(&states, rtc::Optional<int>(bandwidth),
                           rtc::Optional<float>());
      CheckDecision(&states, initial_fec_enabled, 0.0);
    }
  }
}

TEST(FecControllerPlrBasedTest, EnableFecForHighBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
                       kEnablingPacketLossAtHighBw);
  CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
}

TEST(FecControllerPlrBasedTest, UpdateMultipleNetworkMetricsAtOnce) {
  // This test is similar to EnableFecForHighBandwidth. But instead of
  // using ::UpdateNetworkMetrics(...), which calls
  // FecControllerPlrBased::UpdateNetworkMetrics(...) multiple times, we
  // we call it only once. This is to verify that
  // FecControllerPlrBased::UpdateNetworkMetrics(...) can handle multiple
  // network updates at once. This is, however, not a common use case in current
  // audio_network_adaptor_impl.cc.
  auto states = CreateFecControllerPlrBased(false);
  Controller::NetworkMetrics network_metrics;
  network_metrics.uplink_bandwidth_bps =
      rtc::Optional<int>(kEnablingBandwidthHigh);
  network_metrics.uplink_packet_loss_fraction =
      rtc::Optional<float>(kEnablingPacketLossAtHighBw);
  EXPECT_CALL(*states.packet_loss_smoother, GetAverage())
      .WillOnce(Return(rtc::Optional<float>(kEnablingPacketLossAtHighBw)));
  states.controller->UpdateNetworkMetrics(network_metrics);
  CheckDecision(&states, true, kEnablingPacketLossAtHighBw);
}

TEST(FecControllerPlrBasedTest, MaintainFecOffForHighBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  constexpr float kPacketLoss = kEnablingPacketLossAtHighBw * 0.99f;
  UpdateNetworkMetrics(&states, kEnablingBandwidthHigh, kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, EnableFecForMediumBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  constexpr float kPacketLoss =
      (kEnablingPacketLossAtLowBw + kEnablingPacketLossAtHighBw) / 2.0;
  UpdateNetworkMetrics(&states,
                       (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
                       kPacketLoss);
  CheckDecision(&states, true, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, MaintainFecOffForMediumBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  constexpr float kPacketLoss =
      kEnablingPacketLossAtLowBw * 0.49f + kEnablingPacketLossAtHighBw * 0.51f;
  UpdateNetworkMetrics(&states,
                       (kEnablingBandwidthHigh + kEnablingBandwidthLow) / 2,
                       kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, EnableFecForLowBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
                       kEnablingPacketLossAtLowBw);
  CheckDecision(&states, true, kEnablingPacketLossAtLowBw);
}

TEST(FecControllerPlrBasedTest, MaintainFecOffForLowBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  constexpr float kPacketLoss = kEnablingPacketLossAtLowBw * 0.99f;
  UpdateNetworkMetrics(&states, kEnablingBandwidthLow, kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, MaintainFecOffForVeryLowBandwidth) {
  auto states = CreateFecControllerPlrBased(false);
  // Below |kEnablingBandwidthLow|, no packet loss fraction can cause FEC to
  // turn on.
  UpdateNetworkMetrics(&states, kEnablingBandwidthLow - 1, 1.0);
  CheckDecision(&states, false, 1.0);
}

TEST(FecControllerPlrBasedTest, DisableFecForHighBandwidth) {
  auto states = CreateFecControllerPlrBased(true);
  constexpr float kPacketLoss = kDisablingPacketLossAtHighBw - kEpsilon;
  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh, kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, MaintainFecOnForHighBandwidth) {
  // Note: Disabling happens when the value is strictly below the threshold.
  auto states = CreateFecControllerPlrBased(true);
  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
                       kDisablingPacketLossAtHighBw);
  CheckDecision(&states, true, kDisablingPacketLossAtHighBw);
}

TEST(FecControllerPlrBasedTest, DisableFecOnMediumBandwidth) {
  auto states = CreateFecControllerPlrBased(true);
  constexpr float kPacketLoss =
      (kDisablingPacketLossAtLowBw + kDisablingPacketLossAtHighBw) / 2.0f -
      kEpsilon;
  UpdateNetworkMetrics(&states,
                       (kDisablingBandwidthHigh + kDisablingBandwidthLow) / 2,
                       kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, MaintainFecOnForMediumBandwidth) {
  auto states = CreateFecControllerPlrBased(true);
  constexpr float kPacketLoss = kDisablingPacketLossAtLowBw * 0.51f +
                                kDisablingPacketLossAtHighBw * 0.49f - kEpsilon;
  UpdateNetworkMetrics(&states,
                       (kEnablingBandwidthHigh + kDisablingBandwidthLow) / 2,
                       kPacketLoss);
  CheckDecision(&states, true, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, DisableFecForLowBandwidth) {
  auto states = CreateFecControllerPlrBased(true);
  constexpr float kPacketLoss = kDisablingPacketLossAtLowBw - kEpsilon;
  UpdateNetworkMetrics(&states, kDisablingBandwidthLow, kPacketLoss);
  CheckDecision(&states, false, kPacketLoss);
}

TEST(FecControllerPlrBasedTest, DisableFecForVeryLowBandwidth) {
  auto states = CreateFecControllerPlrBased(true);
  // Below |kEnablingBandwidthLow|, any packet loss fraction can cause FEC to
  // turn off.
  UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(&states, false, 1.0);
}

TEST(FecControllerPlrBasedTest, 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 = CreateFecControllerPlrBased(true);
  UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(&states, false, 1.0);

  UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
                       kEnablingPacketLossAtLowBw * 0.99f);
  CheckDecision(&states, false, kEnablingPacketLossAtLowBw * 0.99f);

  UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
                       kEnablingPacketLossAtHighBw);
  CheckDecision(&states, true, kEnablingPacketLossAtHighBw);

  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
                       kDisablingPacketLossAtHighBw);
  CheckDecision(&states, true, kDisablingPacketLossAtHighBw);

  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh + 1, 0.0);
  CheckDecision(&states, false, 0.0);
}

TEST(FecControllerPlrBasedTest, 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;
  FecControllerPlrBasedTestStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoother = mock_smoothing_filter.get();
  states.controller.reset(new FecControllerPlrBased(
      FecControllerPlrBased::Config(
          true,
          ThresholdCurve(kEnablingBandwidthLow, kEnablingPacketLossAtLowBw,
                         kEnablingBandwidthHigh, kEnablingPacketLossAtHighBw),
          ThresholdCurve(kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                         kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
          0),
      std::move(mock_smoothing_filter)));

  UpdateNetworkMetrics(&states, kDisablingBandwidthLow - 1, 1.0);
  CheckDecision(&states, false, 1.0);

  UpdateNetworkMetrics(&states, kEnablingBandwidthLow,
                       kEnablingPacketLossAtHighBw * 0.99f);
  CheckDecision(&states, false, kEnablingPacketLossAtHighBw * 0.99f);

  UpdateNetworkMetrics(&states, kEnablingBandwidthHigh,
                       kEnablingPacketLossAtHighBw);
  CheckDecision(&states, true, kEnablingPacketLossAtHighBw);

  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh,
                       kDisablingPacketLossAtHighBw);
  CheckDecision(&states, true, kDisablingPacketLossAtHighBw);

  UpdateNetworkMetrics(&states, kDisablingBandwidthHigh + 1, 0.0);
  CheckDecision(&states, false, 0.0);
}

TEST(FecControllerPlrBasedTest, SingleThresholdCurveForEnablingAndDisabling) {
  // Note: To avoid numerical errors, keep kPacketLossAtLowBw and
  // kPacketLossAthighBw as (negative) integer powers of 2.
  // This is mostly relevant for the O3 case.
  constexpr int kBandwidthLow = 10000;
  constexpr float kPacketLossAtLowBw = 0.25f;
  constexpr int kBandwidthHigh = 20000;
  constexpr float kPacketLossAtHighBw = 0.125f;
  auto curve = ThresholdCurve(kBandwidthLow, kPacketLossAtLowBw, kBandwidthHigh,
                              kPacketLossAtHighBw);

  // B* stands for "below-curve", O* for "on-curve", and A* for "above-curve".
  //
  //                                            //
  // packet-loss ^                              //
  //             |    |                         //
  //             | B1 O1                        //
  //             |    |                         //
  //             |    O2                        //
  //             |     \ A1                     //
  //             |      \                       //
  //             |       O3   A2                //
  //             |     B2 \                     //
  //             |         \                    //
  //             |          O4--O5----          //
  //             |                              //
  //             |            B3                //
  //             |-----------------> bandwidth  //

  struct NetworkState {
    int bandwidth;
    float packet_loss;
  };

  std::vector<NetworkState> below{
      {kBandwidthLow - 1, kPacketLossAtLowBw + 0.1f},  // B1
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2 - kEpsilon},  // B2
      {kBandwidthHigh + 1, kPacketLossAtHighBw - kEpsilon}          // B3
  };

  std::vector<NetworkState> on{
      {kBandwidthLow, kPacketLossAtLowBw + 0.1f},  // O1
      {kBandwidthLow, kPacketLossAtLowBw},         // O2
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2},  // O3
      {kBandwidthHigh, kPacketLossAtHighBw},             // O4
      {kBandwidthHigh + 1, kPacketLossAtHighBw},         // O5
  };

  std::vector<NetworkState> above{
      {(kBandwidthLow + kBandwidthHigh) / 2,
       (kPacketLossAtLowBw + kPacketLossAtHighBw) / 2 + kEpsilon},  // A1
      {kBandwidthHigh + 1, kPacketLossAtHighBw + kEpsilon},         // A2
  };

  // Test that FEC is turned off whenever we're below the curve, independent
  // of the starting FEC state.
  for (NetworkState net_state : below) {
    for (bool initial_fec_enabled : {false, true}) {
      auto states =
          CreateFecControllerPlrBased(initial_fec_enabled, curve, curve);
      UpdateNetworkMetrics(&states, net_state.bandwidth, net_state.packet_loss);
      CheckDecision(&states, false, net_state.packet_loss);
    }
  }

  // Test that FEC is turned on whenever we're on the curve or above it,
  // independent of the starting FEC state.
  for (std::vector<NetworkState> states_list : {on, above}) {
    for (NetworkState net_state : states_list) {
      for (bool initial_fec_enabled : {false, true}) {
        auto states =
            CreateFecControllerPlrBased(initial_fec_enabled, curve, curve);
        UpdateNetworkMetrics(&states, net_state.bandwidth,
                             net_state.packet_loss);
        CheckDecision(&states, true, net_state.packet_loss);
      }
    }
  }
}

TEST(FecControllerPlrBasedTest, FecAlwaysOff) {
  ThresholdCurve always_off_curve(0, 1.0f + kEpsilon, 0, 1.0f + kEpsilon);
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {0, 10000}) {
      for (float packet_loss : {0.0f, 0.5f, 1.0f}) {
        auto states = CreateFecControllerPlrBased(
            initial_fec_enabled, always_off_curve, always_off_curve);
        UpdateNetworkMetrics(&states, bandwidth, packet_loss);
        CheckDecision(&states, false, packet_loss);
      }
    }
  }
}

TEST(FecControllerPlrBasedTest, FecAlwaysOn) {
  ThresholdCurve always_on_curve(0, 0.0f, 0, 0.0f);
  for (bool initial_fec_enabled : {false, true}) {
    for (int bandwidth : {0, 10000}) {
      for (float packet_loss : {0.0f, 0.5f, 1.0f}) {
        auto states = CreateFecControllerPlrBased(
            initial_fec_enabled, always_on_curve, always_on_curve);
        UpdateNetworkMetrics(&states, bandwidth, packet_loss);
        CheckDecision(&states, true, packet_loss);
      }
    }
  }
}

#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
TEST(FecControllerPlrBasedDeathTest, InvalidConfig) {
  FecControllerPlrBasedTestStates states;
  std::unique_ptr<MockSmoothingFilter> mock_smoothing_filter(
      new NiceMock<MockSmoothingFilter>());
  states.packet_loss_smoother = mock_smoothing_filter.get();
  EXPECT_DEATH(
      states.controller.reset(new FecControllerPlrBased(
          FecControllerPlrBased::Config(
              true,
              ThresholdCurve(kDisablingBandwidthLow - 1,
                             kEnablingPacketLossAtLowBw, kEnablingBandwidthHigh,
                             kEnablingPacketLossAtHighBw),
              ThresholdCurve(
                  kDisablingBandwidthLow, kDisablingPacketLossAtLowBw,
                  kDisablingBandwidthHigh, kDisablingPacketLossAtHighBw),
              0),
          std::move(mock_smoothing_filter))),
      "Check failed");
}
#endif

}  // namespace webrtc
