/*
 *  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 absl::optional<int>& uplink_bandwidth_bps,
                          const absl::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, absl::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, absl::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 (const 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
