/*
 *  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 "common_audio/mocks/mock_smoothing_filter.h"
#include "modules/audio_coding/audio_network_adaptor/fec_controller_plr_based.h"
#include "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(*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(expected_enable_fec, config.enable_fec);
  EXPECT_EQ(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::nullopt, 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, bandwidth, rtc::nullopt);
      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 = kEnablingBandwidthHigh;
  network_metrics.uplink_packet_loss_fraction = kEnablingPacketLossAtHighBw;
  EXPECT_CALL(*states.packet_loss_smoother, GetAverage())
      .WillOnce(Return(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
