/*
 *  Copyright (c) 2018 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 "modules/congestion_controller/pcc/monitor_interval.h"

#include <stddef.h>

#include "test/gtest.h"

namespace webrtc {
namespace pcc {
namespace test {
namespace {
const DataRate kTargetSendingRate = DataRate::kbps(300);
const Timestamp kStartTime = Timestamp::us(0);
const TimeDelta kPacketsDelta = TimeDelta::ms(1);
const TimeDelta kIntervalDuration = TimeDelta::ms(100);
const TimeDelta kDefaultDelay = TimeDelta::ms(100);
const DataSize kDefaultPacketSize = DataSize::bytes(100);
constexpr double kDelayGradientThreshold = 0.01;

std::vector<PacketResult> CreatePacketResults(
    const std::vector<Timestamp>& packets_send_times,
    const std::vector<Timestamp>& packets_received_times = {},
    const std::vector<DataSize>& packets_sizes = {}) {
  std::vector<PacketResult> packet_results;
  for (size_t i = 0; i < packets_send_times.size(); ++i) {
    SentPacket sent_packet;
    sent_packet.send_time = packets_send_times[i];
    if (packets_sizes.empty()) {
      sent_packet.size = kDefaultPacketSize;
    } else {
      sent_packet.size = packets_sizes[i];
    }
    PacketResult packet_result;
    packet_result.sent_packet = sent_packet;
    if (packets_received_times.empty()) {
      packet_result.receive_time = packets_send_times[i] + kDefaultDelay;
    } else {
      packet_result.receive_time = packets_received_times[i];
    }
    packet_results.push_back(packet_result);
  }
  return packet_results;
}

}  // namespace

TEST(PccMonitorIntervalTest, InitialValuesAreEqualToOnesSetInConstructor) {
  PccMonitorInterval interval{kTargetSendingRate, kStartTime,
                              kIntervalDuration};
  EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
  EXPECT_EQ(interval.GetEndTime(), kStartTime + kIntervalDuration);
  EXPECT_EQ(interval.GetTargetSendingRate(), kTargetSendingRate);
}

TEST(PccMonitorIntervalTest, IndicatesDoneWhenFeedbackReceivedAfterInterval) {
  PccMonitorInterval interval{kTargetSendingRate, kStartTime,
                              kIntervalDuration};
  interval.OnPacketsFeedback(CreatePacketResults({kStartTime}));
  EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
  interval.OnPacketsFeedback(
      CreatePacketResults({kStartTime, kStartTime + kIntervalDuration}));
  EXPECT_EQ(interval.IsFeedbackCollectionDone(), false);
  interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kIntervalDuration, kStartTime + 2 * kIntervalDuration}));
  EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);
}

TEST(PccMonitorIntervalTest, LossRateIsOneThirdIfLostOnePacketOutOfThree) {
  PccMonitorInterval interval{kTargetSendingRate, kStartTime,
                              kIntervalDuration};
  std::vector<Timestamp> start_times = {
      kStartTime, kStartTime + 0.1 * kIntervalDuration,
      kStartTime + 0.5 * kIntervalDuration, kStartTime + kIntervalDuration,
      kStartTime + 2 * kIntervalDuration};
  std::vector<Timestamp> end_times = {
      kStartTime + 2 * kIntervalDuration, kStartTime + 2 * kIntervalDuration,
      Timestamp::PlusInfinity(), kStartTime + 2 * kIntervalDuration,
      kStartTime + 4 * kIntervalDuration};
  std::vector<DataSize> packet_sizes = {
      kDefaultPacketSize, 2 * kDefaultPacketSize, 3 * kDefaultPacketSize,
      4 * kDefaultPacketSize, 5 * kDefaultPacketSize};
  std::vector<PacketResult> packet_results =
      CreatePacketResults(start_times, end_times, packet_sizes);
  interval.OnPacketsFeedback(packet_results);
  EXPECT_EQ(interval.IsFeedbackCollectionDone(), true);

  EXPECT_DOUBLE_EQ(interval.GetLossRate(), 1. / 3);
}

TEST(PccMonitorIntervalTest, DelayGradientIsZeroIfNoChangeInPacketDelay) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
       kStartTime + 3 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
      {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
       kStartTime + kDefaultDelay + 2 * kPacketsDelta,
       Timestamp::PlusInfinity()},
      {}));
  // Delay gradient should be zero, because both received packets have the
  // same one way delay.
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}

TEST(PccMonitorIntervalTest,
     DelayGradientIsZeroWhenOnePacketSentInMonitorInterval) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
      {kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration}, {}));
  // Only one received packet belongs to the monitor_interval, delay gradient
  // should be zero in this case.
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}

TEST(PccMonitorIntervalTest, DelayGradientIsOne) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
       kStartTime + 3 * kPacketsDelta, kStartTime + 3 * kIntervalDuration},
      {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
       kStartTime + 4 * kPacketsDelta + kDefaultDelay,
       kStartTime + 3 * kIntervalDuration},
      {}));
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 1);
}

TEST(PccMonitorIntervalTest, DelayGradientIsMinusOne) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + 2 * kPacketsDelta,
       kStartTime + 5 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
      {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
       kStartTime + kDefaultDelay, kStartTime + 3 * kIntervalDuration},
      {}));
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), -1);
}

TEST(PccMonitorIntervalTest,
     DelayGradientIsZeroIfItSmallerWhenGradientThreshold) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
       kStartTime + 102 * kPacketsDelta, kStartTime + 2 * kIntervalDuration},
      {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
       kStartTime + kDefaultDelay + kPacketsDelta,
       kStartTime + 3 * kIntervalDuration},
      {}));
  // Delay gradient is less than 0.01 hence should be treated as zero.
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}

TEST(PccMonitorIntervalTest,
     DelayGradientIsZeroWhenAllPacketsSentAtTheSameTime) {
  PccMonitorInterval monitor_interval(kTargetSendingRate, kStartTime,
                                      kIntervalDuration);
  monitor_interval.OnPacketsFeedback(CreatePacketResults(
      {kStartTime + kPacketsDelta, kStartTime + kPacketsDelta,
       kStartTime + kPacketsDelta, kStartTime + 2 * kIntervalDuration},
      {kStartTime + kDefaultDelay, Timestamp::PlusInfinity(),
       kStartTime + kDefaultDelay + kPacketsDelta,
       kStartTime + 3 * kIntervalDuration},
      {}));
  // If all packets were sent at the same time, then delay gradient should be
  // zero.
  EXPECT_DOUBLE_EQ(
      monitor_interval.ComputeDelayGradient(kDelayGradientThreshold), 0);
}

}  // namespace test
}  // namespace pcc
}  // namespace webrtc
