/*
 *  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 <memory>
#include <utility>

#include "modules/audio_coding/audio_network_adaptor/frame_length_controller.h"
#include "test/gtest.h"

namespace webrtc {

namespace {

constexpr float kFlIncreasingPacketLossFraction = 0.04f;
constexpr float kFlDecreasingPacketLossFraction = 0.05f;
constexpr int kFlIncreaseOverheadOffset = 0;
constexpr int kFlDecreaseOverheadOffset = 0;
constexpr int kMinEncoderBitrateBps = 6000;
constexpr int kPreventOveruseMarginBps = 5000;
constexpr size_t kOverheadBytesPerPacket = 20;
constexpr int kFl20msTo60msBandwidthBps = 40000;
constexpr int kFl60msTo20msBandwidthBps = 50000;
constexpr int kFl60msTo120msBandwidthBps = 30000;
constexpr int kFl120msTo60msBandwidthBps = 40000;
constexpr int kMediumBandwidthBps =
    (kFl60msTo20msBandwidthBps + kFl20msTo60msBandwidthBps) / 2;
constexpr float kMediumPacketLossFraction =
    (kFlDecreasingPacketLossFraction + kFlIncreasingPacketLossFraction) / 2;

int VeryLowBitrate(int frame_length_ms) {
  return kMinEncoderBitrateBps + kPreventOveruseMarginBps +
         (kOverheadBytesPerPacket * 8 * 1000 / frame_length_ms);
}

std::unique_ptr<FrameLengthController> CreateController(
    const std::map<FrameLengthController::Config::FrameLengthChange, int>&
        frame_length_change_criteria,
    const std::set<int>& encoder_frame_lengths_ms,
    int initial_frame_length_ms) {
  std::unique_ptr<FrameLengthController> controller(
      new FrameLengthController(FrameLengthController::Config(
          encoder_frame_lengths_ms, initial_frame_length_ms,
          kMinEncoderBitrateBps, kFlIncreasingPacketLossFraction,
          kFlDecreasingPacketLossFraction, kFlIncreaseOverheadOffset,
          kFlDecreaseOverheadOffset, frame_length_change_criteria)));

  return controller;
}

std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20msAnd60ms() {
  return std::map<FrameLengthController::Config::FrameLengthChange, int>{
      {FrameLengthController::Config::FrameLengthChange(20, 60),
       kFl20msTo60msBandwidthBps},
      {FrameLengthController::Config::FrameLengthChange(60, 20),
       kFl60msTo20msBandwidthBps}};
}

std::map<FrameLengthController::Config::FrameLengthChange, int>
CreateChangeCriteriaFor20ms60msAnd120ms() {
  return std::map<FrameLengthController::Config::FrameLengthChange, int>{
      {FrameLengthController::Config::FrameLengthChange(20, 60),
       kFl20msTo60msBandwidthBps},
      {FrameLengthController::Config::FrameLengthChange(60, 20),
       kFl60msTo20msBandwidthBps},
      {FrameLengthController::Config::FrameLengthChange(60, 120),
       kFl60msTo120msBandwidthBps},
      {FrameLengthController::Config::FrameLengthChange(120, 60),
       kFl120msTo60msBandwidthBps}};
}

void UpdateNetworkMetrics(
    FrameLengthController* controller,
    const absl::optional<int>& uplink_bandwidth_bps,
    const absl::optional<float>& uplink_packet_loss_fraction,
    const absl::optional<size_t>& overhead_bytes_per_packet) {
  // 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;
    controller->UpdateNetworkMetrics(network_metrics);
  }
  if (uplink_packet_loss_fraction) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.uplink_packet_loss_fraction = uplink_packet_loss_fraction;
    controller->UpdateNetworkMetrics(network_metrics);
  }
  if (overhead_bytes_per_packet) {
    Controller::NetworkMetrics network_metrics;
    network_metrics.overhead_bytes_per_packet = overhead_bytes_per_packet;
    controller->UpdateNetworkMetrics(network_metrics);
  }
}

void CheckDecision(FrameLengthController* controller,
                   int expected_frame_length_ms) {
  AudioEncoderRuntimeConfig config;
  controller->MakeDecision(&config);
  EXPECT_EQ(expected_frame_length_ms, config.frame_length_ms);
}

}  // namespace

TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkBandwidth) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
  UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
                       absl::nullopt, kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, DecreaseTo20MsOnHighUplinkPacketLossFraction) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
  UpdateNetworkMetrics(controller.get(), absl::nullopt,
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest,
     Maintain60MsIf20MsNotInReceiverFrameLengthRange) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {60}, 60);
  // Set FEC on that would cause frame length to decrease if receiver frame
  // length range included 20ms.
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, Maintain60MsOnMultipleConditions) {
  // Maintain 60ms frame length if
  // 1. |uplink_bandwidth_bps| is at medium level,
  // 2. |uplink_packet_loss_fraction| is at medium,
  // 3. FEC is not decided ON.
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
  UpdateNetworkMetrics(controller.get(), kMediumBandwidthBps,
                       kMediumPacketLossFraction, kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, IncreaseTo60MsOnMultipleConditions) {
  // Increase to 60ms frame length if
  // 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND
  // 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold
  //    AND
  // 3. FEC is not decided or OFF.
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
  UpdateNetworkMetrics(controller.get(), kFl20msTo60msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, IncreaseTo60MsOnVeryLowUplinkBandwidth) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
  // We set packet loss fraction to kFlDecreasingPacketLossFraction, which
  // should have prevented frame length to increase, if the uplink bandwidth
  // was not this low.
  UpdateNetworkMetrics(controller.get(), VeryLowBitrate(20),
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, Maintain60MsOnVeryLowUplinkBandwidth) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 60);
  // We set packet loss fraction to FlDecreasingPacketLossFraction, which should
  // have caused the frame length to decrease, if the uplink bandwidth was not
  // this low.
  UpdateNetworkMetrics(controller.get(), VeryLowBitrate(20),
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, UpdateMultipleNetworkMetricsAtOnce) {
  // This test is similar to IncreaseTo60MsOnMultipleConditions. But instead of
  // using ::UpdateNetworkMetrics(...), which calls
  // FrameLengthController::UpdateNetworkMetrics(...) multiple times, we
  // we call it only once. This is to verify that
  // FrameLengthController::UpdateNetworkMetrics(...) can handle multiple
  // network updates at once. This is, however, not a common use case in current
  // audio_network_adaptor_impl.cc.
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
  Controller::NetworkMetrics network_metrics;
  network_metrics.uplink_bandwidth_bps = kFl20msTo60msBandwidthBps;
  network_metrics.uplink_packet_loss_fraction = kFlIncreasingPacketLossFraction;
  controller->UpdateNetworkMetrics(network_metrics);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest,
     Maintain20MsIf60MsNotInReceiverFrameLengthRange) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20}, 20);
  // Use a low uplink bandwidth and a low uplink packet loss fraction that would
  // cause frame length to increase if receiver frame length included 60ms.
  UpdateNetworkMetrics(controller.get(),
                       kFl20msTo60msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkBandwidth) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
  UpdateNetworkMetrics(controller.get(),
                       kMediumBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, Maintain20MsOnMediumUplinkPacketLossFraction) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60}, 20);
  // Use a low uplink bandwidth that would cause frame length to increase if
  // uplink packet loss fraction was low.
  UpdateNetworkMetrics(controller.get(),
                       kFl20msTo60msBandwidthBps,
                       kMediumPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, Maintain60MsWhenNo120msCriteriaIsSet) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20msAnd60ms(), {20, 60, 120}, 60);
  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkBandwidth) {
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 120);
  // It takes two steps for frame length to go from 120ms to 20ms.
  UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
                       absl::nullopt, kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);

  UpdateNetworkMetrics(controller.get(), kFl60msTo20msBandwidthBps,
                       absl::nullopt, kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, From120MsTo20MsOnHighUplinkPacketLossFraction) {
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 120);
  // It takes two steps for frame length to go from 120ms to 20ms.
  UpdateNetworkMetrics(controller.get(), absl::nullopt,
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);

  UpdateNetworkMetrics(controller.get(), absl::nullopt,
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

TEST(FrameLengthControllerTest, Maintain120MsOnVeryLowUplinkBandwidth) {
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 120);
  // We set packet loss fraction to FlDecreasingPacketLossFraction, which should
  // have caused the frame length to decrease, if the uplink bandwidth was not
  // this low.
  UpdateNetworkMetrics(controller.get(), VeryLowBitrate(60),
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 120);
}

TEST(FrameLengthControllerTest, From60MsTo120MsOnVeryLowUplinkBandwidth) {
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 60);
  // We set packet loss fraction to FlDecreasingPacketLossFraction, which should
  // have prevented frame length to increase, if the uplink bandwidth was not
  // this low.
  UpdateNetworkMetrics(controller.get(), VeryLowBitrate(60),
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 120);
}

TEST(FrameLengthControllerTest, From20MsTo120MsOnMultipleConditions) {
  // Increase to 120ms frame length if
  // 1. |uplink_bandwidth_bps| is known to be smaller than a threshold AND
  // 2. |uplink_packet_loss_fraction| is known to be smaller than a threshold.
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 20);
  // It takes two steps for frame length to go from 20ms to 120ms.
  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 120);
}

TEST(FrameLengthControllerTest, Stall60MsIf120MsNotInReceiverFrameLengthRange) {
  auto controller =
      CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(), {20, 60}, 20);
  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);
}

TEST(FrameLengthControllerTest, CheckBehaviorOnChangingNetworkMetrics) {
  auto controller = CreateController(CreateChangeCriteriaFor20ms60msAnd120ms(),
                                     {20, 60, 120}, 20);
  UpdateNetworkMetrics(controller.get(),
                       kMediumBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);

  UpdateNetworkMetrics(controller.get(),
                       kFl20msTo60msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);

  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kMediumPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);

  UpdateNetworkMetrics(controller.get(),
                       kFl60msTo120msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 120);

  UpdateNetworkMetrics(controller.get(),
                       kFl120msTo60msBandwidthBps,
                       kFlIncreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 60);

  UpdateNetworkMetrics(controller.get(),
                       kMediumBandwidthBps,
                       kFlDecreasingPacketLossFraction,
                       kOverheadBytesPerPacket);
  CheckDecision(controller.get(), 20);
}

}  // namespace webrtc
