/*
 *  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 "modules/congestion_controller/goog_cc/delay_based_bwe_unittest_helper.h"

#include <algorithm>
#include <cstdint>

#include "absl/memory/memory.h"
#include "modules/congestion_controller/goog_cc/delay_based_bwe.h"
#include "rtc_base/checks.h"

namespace webrtc {
constexpr size_t kMtu = 1200;
constexpr uint32_t kAcceptedBitrateErrorBps = 50000;

// Number of packets needed before we have a valid estimate.
constexpr int kNumInitialPackets = 2;

constexpr int kInitialProbingPackets = 5;

namespace test {

void TestBitrateObserver::OnReceiveBitrateChanged(uint32_t bitrate) {
  latest_bitrate_ = bitrate;
  updated_ = true;
}

RtpStream::RtpStream(int fps, int bitrate_bps)
    : fps_(fps), bitrate_bps_(bitrate_bps), next_rtp_time_(0) {
  RTC_CHECK_GT(fps_, 0);
}

// Generates a new frame for this stream. If called too soon after the
// previous frame, no frame will be generated. The frame is split into
// packets.
int64_t RtpStream::GenerateFrame(int64_t time_now_us,
                                 std::vector<PacketResult>* packets) {
  if (time_now_us < next_rtp_time_) {
    return next_rtp_time_;
  }
  RTC_CHECK(packets != NULL);
  size_t bits_per_frame = (bitrate_bps_ + fps_ / 2) / fps_;
  size_t n_packets =
      std::max<size_t>((bits_per_frame + 4 * kMtu) / (8 * kMtu), 1u);
  size_t payload_size = (bits_per_frame + 4 * n_packets) / (8 * n_packets);
  for (size_t i = 0; i < n_packets; ++i) {
    PacketResult packet;
    packet.sent_packet.send_time =
        Timestamp::us(time_now_us + kSendSideOffsetUs);
    packet.sent_packet.size = DataSize::bytes(payload_size);
    packets->push_back(packet);
  }
  next_rtp_time_ = time_now_us + (1000000 + fps_ / 2) / fps_;
  return next_rtp_time_;
}

// The send-side time when the next frame can be generated.
int64_t RtpStream::next_rtp_time() const {
  return next_rtp_time_;
}

void RtpStream::set_bitrate_bps(int bitrate_bps) {
  ASSERT_GE(bitrate_bps, 0);
  bitrate_bps_ = bitrate_bps;
}

int RtpStream::bitrate_bps() const {
  return bitrate_bps_;
}

bool RtpStream::Compare(const std::unique_ptr<RtpStream>& lhs,
                        const std::unique_ptr<RtpStream>& rhs) {
  return lhs->next_rtp_time_ < rhs->next_rtp_time_;
}

StreamGenerator::StreamGenerator(int capacity, int64_t time_now)
    : capacity_(capacity), prev_arrival_time_us_(time_now) {}

StreamGenerator::~StreamGenerator() = default;

// Add a new stream.
void StreamGenerator::AddStream(RtpStream* stream) {
  streams_.push_back(std::unique_ptr<RtpStream>(stream));
}

// Set the link capacity.
void StreamGenerator::set_capacity_bps(int capacity_bps) {
  ASSERT_GT(capacity_bps, 0);
  capacity_ = capacity_bps;
}

// Divides |bitrate_bps| among all streams. The allocated bitrate per stream
// is decided by the current allocation ratios.
void StreamGenerator::SetBitrateBps(int bitrate_bps) {
  ASSERT_GE(streams_.size(), 0u);
  int total_bitrate_before = 0;
  for (const auto& stream : streams_) {
    total_bitrate_before += stream->bitrate_bps();
  }
  int64_t bitrate_before = 0;
  int total_bitrate_after = 0;
  for (const auto& stream : streams_) {
    bitrate_before += stream->bitrate_bps();
    int64_t bitrate_after =
        (bitrate_before * bitrate_bps + total_bitrate_before / 2) /
        total_bitrate_before;
    stream->set_bitrate_bps(bitrate_after - total_bitrate_after);
    total_bitrate_after += stream->bitrate_bps();
  }
  ASSERT_EQ(bitrate_before, total_bitrate_before);
  EXPECT_EQ(total_bitrate_after, bitrate_bps);
}

// TODO(holmer): Break out the channel simulation part from this class to make
// it possible to simulate different types of channels.
int64_t StreamGenerator::GenerateFrame(std::vector<PacketResult>* packets,
                                       int64_t time_now_us) {
  RTC_CHECK(packets != NULL);
  RTC_CHECK(packets->empty());
  RTC_CHECK_GT(capacity_, 0);
  auto it =
      std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
  (*it)->GenerateFrame(time_now_us, packets);
  int i = 0;
  for (PacketResult& packet : *packets) {
    int capacity_bpus = capacity_ / 1000;
    int64_t required_network_time_us =
        (8 * 1000 * packet.sent_packet.size.bytes() + capacity_bpus / 2) /
        capacity_bpus;
    prev_arrival_time_us_ =
        std::max(time_now_us + required_network_time_us,
                 prev_arrival_time_us_ + required_network_time_us);
    packet.receive_time = Timestamp::us(prev_arrival_time_us_);
    ++i;
  }
  it = std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
  return std::max((*it)->next_rtp_time(), time_now_us);
}
}  // namespace test

DelayBasedBweTest::DelayBasedBweTest()
    : field_trial(),
      clock_(100000000),
      acknowledged_bitrate_estimator_(
          absl::make_unique<AcknowledgedBitrateEstimator>(
              &field_trial_config_)),
      probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
      bitrate_estimator_(
          new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)),
      stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                  clock_.TimeInMicroseconds())),
      arrival_time_offset_ms_(0),
      first_update_(true) {}

DelayBasedBweTest::DelayBasedBweTest(const std::string& field_trial_string)
    : field_trial(
          absl::make_unique<test::ScopedFieldTrials>(field_trial_string)),
      clock_(100000000),
      acknowledged_bitrate_estimator_(
          absl::make_unique<AcknowledgedBitrateEstimator>(
              &field_trial_config_)),
      probe_bitrate_estimator_(new ProbeBitrateEstimator(nullptr)),
      bitrate_estimator_(
          new DelayBasedBwe(&field_trial_config_, nullptr, nullptr)),
      stream_generator_(new test::StreamGenerator(1e6,  // Capacity.
                                                  clock_.TimeInMicroseconds())),
      arrival_time_offset_ms_(0),
      first_update_(true) {}

DelayBasedBweTest::~DelayBasedBweTest() {}

void DelayBasedBweTest::AddDefaultStream() {
  stream_generator_->AddStream(new test::RtpStream(30, 3e5));
}

const uint32_t DelayBasedBweTest::kDefaultSsrc = 0;

void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
                                         int64_t send_time_ms,
                                         size_t payload_size) {
  IncomingFeedback(arrival_time_ms, send_time_ms, payload_size,
                   PacedPacketInfo());
}

void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
                                         int64_t send_time_ms,
                                         size_t payload_size,
                                         const PacedPacketInfo& pacing_info) {
  RTC_CHECK_GE(arrival_time_ms + arrival_time_offset_ms_, 0);
  PacketResult packet;
  packet.receive_time =
      Timestamp::ms(arrival_time_ms + arrival_time_offset_ms_);
  packet.sent_packet.send_time = Timestamp::ms(send_time_ms);
  packet.sent_packet.size = DataSize::bytes(payload_size);
  packet.sent_packet.pacing_info = pacing_info;
  if (packet.sent_packet.pacing_info.probe_cluster_id !=
      PacedPacketInfo::kNotAProbe)
    probe_bitrate_estimator_->HandleProbeAndEstimateBitrate(packet);

  TransportPacketsFeedback msg;
  msg.feedback_time = Timestamp::ms(clock_.TimeInMilliseconds());
  msg.packet_feedbacks.push_back(packet);
  acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(
      msg.SortedByReceiveTime());
  DelayBasedBwe::Result result =
      bitrate_estimator_->IncomingPacketFeedbackVector(
          msg, acknowledged_bitrate_estimator_->bitrate(),
          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
          /*network_estimate*/ absl::nullopt, /*in_alr*/ false);
  if (result.updated) {
    bitrate_observer_.OnReceiveBitrateChanged(result.target_bitrate.bps());
  }
}

// Generates a frame of packets belonging to a stream at a given bitrate and
// with a given ssrc. The stream is pushed through a very simple simulated
// network, and is then given to the receive-side bandwidth estimator.
// Returns true if an over-use was seen, false otherwise.
// The StreamGenerator::updated() should be used to check for any changes in
// target bitrate after the call to this function.
bool DelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc,
                                                uint32_t bitrate_bps) {
  stream_generator_->SetBitrateBps(bitrate_bps);
  std::vector<PacketResult> packets;

  int64_t next_time_us =
      stream_generator_->GenerateFrame(&packets, clock_.TimeInMicroseconds());
  if (packets.empty())
    return false;

  bool overuse = false;
  bitrate_observer_.Reset();
  clock_.AdvanceTimeMicroseconds(packets.back().receive_time.us() -
                                 clock_.TimeInMicroseconds());
  for (auto& packet : packets) {
    RTC_CHECK_GE(packet.receive_time.ms() + arrival_time_offset_ms_, 0);
    packet.receive_time += TimeDelta::ms(arrival_time_offset_ms_);

    if (packet.sent_packet.pacing_info.probe_cluster_id !=
        PacedPacketInfo::kNotAProbe)
      probe_bitrate_estimator_->HandleProbeAndEstimateBitrate(packet);
  }

  acknowledged_bitrate_estimator_->IncomingPacketFeedbackVector(packets);
  TransportPacketsFeedback msg;
  msg.packet_feedbacks = packets;
  msg.feedback_time = Timestamp::ms(clock_.TimeInMilliseconds());

  DelayBasedBwe::Result result =
      bitrate_estimator_->IncomingPacketFeedbackVector(
          msg, acknowledged_bitrate_estimator_->bitrate(),
          probe_bitrate_estimator_->FetchAndResetLastEstimatedBitrate(),
          /*network_estimate*/ absl::nullopt, /*in_alr*/ false);
  if (result.updated) {
    bitrate_observer_.OnReceiveBitrateChanged(result.target_bitrate.bps());
    if (!first_update_ && result.target_bitrate.bps() < bitrate_bps)
      overuse = true;
    first_update_ = false;
  }

  clock_.AdvanceTimeMicroseconds(next_time_us - clock_.TimeInMicroseconds());
  return overuse;
}

// Run the bandwidth estimator with a stream of |number_of_frames| frames, or
// until it reaches |target_bitrate|.
// Can for instance be used to run the estimator for some time to get it
// into a steady state.
uint32_t DelayBasedBweTest::SteadyStateRun(uint32_t ssrc,
                                           int max_number_of_frames,
                                           uint32_t start_bitrate,
                                           uint32_t min_bitrate,
                                           uint32_t max_bitrate,
                                           uint32_t target_bitrate) {
  uint32_t bitrate_bps = start_bitrate;
  bool bitrate_update_seen = false;
  // Produce |number_of_frames| frames and give them to the estimator.
  for (int i = 0; i < max_number_of_frames; ++i) {
    bool overuse = GenerateAndProcessFrame(ssrc, bitrate_bps);
    if (overuse) {
      EXPECT_LT(bitrate_observer_.latest_bitrate(), max_bitrate);
      EXPECT_GT(bitrate_observer_.latest_bitrate(), min_bitrate);
      bitrate_bps = bitrate_observer_.latest_bitrate();
      bitrate_update_seen = true;
    } else if (bitrate_observer_.updated()) {
      bitrate_bps = bitrate_observer_.latest_bitrate();
      bitrate_observer_.Reset();
    }
    if (bitrate_update_seen && bitrate_bps > target_bitrate) {
      break;
    }
  }
  EXPECT_TRUE(bitrate_update_seen);
  return bitrate_bps;
}

void DelayBasedBweTest::InitialBehaviorTestHelper(
    uint32_t expected_converge_bitrate) {
  const int kFramerate = 50;  // 50 fps to avoid rounding errors.
  const int kFrameIntervalMs = 1000 / kFramerate;
  const PacedPacketInfo kPacingInfo(0, 5, 5000);
  DataRate bitrate = DataRate::Zero();
  int64_t send_time_ms = 0;
  std::vector<uint32_t> ssrcs;
  EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
  EXPECT_EQ(0u, ssrcs.size());
  clock_.AdvanceTimeMilliseconds(1000);
  EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
  EXPECT_FALSE(bitrate_observer_.updated());
  bitrate_observer_.Reset();
  clock_.AdvanceTimeMilliseconds(1000);
  // Inserting packets for 5 seconds to get a valid estimate.
  for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
    // NOTE!!! If the following line is moved under the if case then this test
    //         wont work on windows realease bots.
    PacedPacketInfo pacing_info =
        i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo();

    if (i == kNumInitialPackets) {
      EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
      EXPECT_EQ(0u, ssrcs.size());
      EXPECT_FALSE(bitrate_observer_.updated());
      bitrate_observer_.Reset();
    }
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, kMtu,
                     pacing_info);
    clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
    send_time_ms += kFrameIntervalMs;
  }
  EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate));
  ASSERT_EQ(1u, ssrcs.size());
  EXPECT_EQ(kDefaultSsrc, ssrcs.front());
  EXPECT_NEAR(expected_converge_bitrate, bitrate.bps(),
              kAcceptedBitrateErrorBps);
  EXPECT_TRUE(bitrate_observer_.updated());
  bitrate_observer_.Reset();
  EXPECT_EQ(bitrate_observer_.latest_bitrate(), bitrate.bps());
}

void DelayBasedBweTest::RateIncreaseReorderingTestHelper(
    uint32_t expected_bitrate_bps) {
  const int kFramerate = 50;  // 50 fps to avoid rounding errors.
  const int kFrameIntervalMs = 1000 / kFramerate;
  const PacedPacketInfo kPacingInfo(0, 5, 5000);
  int64_t send_time_ms = 0;
  // Inserting packets for five seconds to get a valid estimate.
  for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
    // NOTE!!! If the following line is moved under the if case then this test
    //         wont work on windows realease bots.
    PacedPacketInfo pacing_info =
        i < kInitialProbingPackets ? kPacingInfo : PacedPacketInfo();

    // TODO(sprang): Remove this hack once the single stream estimator is gone,
    // as it doesn't do anything in Process().
    if (i == kNumInitialPackets) {
      // Process after we have enough frames to get a valid input rate estimate.

      EXPECT_FALSE(bitrate_observer_.updated());  // No valid estimate.
    }
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, kMtu,
                     pacing_info);
    clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
    send_time_ms += kFrameIntervalMs;
  }
  EXPECT_TRUE(bitrate_observer_.updated());
  EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_.latest_bitrate(),
              kAcceptedBitrateErrorBps);
  for (int i = 0; i < 10; ++i) {
    clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
    send_time_ms += 2 * kFrameIntervalMs;
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, 1000);
    IncomingFeedback(clock_.TimeInMilliseconds(),
                     send_time_ms - kFrameIntervalMs, 1000);
  }
  EXPECT_TRUE(bitrate_observer_.updated());
  EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_.latest_bitrate(),
              kAcceptedBitrateErrorBps);
}

// Make sure we initially increase the bitrate as expected.
void DelayBasedBweTest::RateIncreaseRtpTimestampsTestHelper(
    int expected_iterations) {
  // This threshold corresponds approximately to increasing linearly with
  // bitrate(i) = 1.04 * bitrate(i-1) + 1000
  // until bitrate(i) > 500000, with bitrate(1) ~= 30000.
  uint32_t bitrate_bps = 30000;
  int iterations = 0;
  AddDefaultStream();
  // Feed the estimator with a stream of packets and verify that it reaches
  // 500 kbps at the expected time.
  while (bitrate_bps < 5e5) {
    bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
    if (overuse) {
      EXPECT_GT(bitrate_observer_.latest_bitrate(), bitrate_bps);
      bitrate_bps = bitrate_observer_.latest_bitrate();
      bitrate_observer_.Reset();
    } else if (bitrate_observer_.updated()) {
      bitrate_bps = bitrate_observer_.latest_bitrate();
      bitrate_observer_.Reset();
    }
    ++iterations;
  }
  ASSERT_EQ(expected_iterations, iterations);
}

void DelayBasedBweTest::CapacityDropTestHelper(
    int number_of_streams,
    bool wrap_time_stamp,
    uint32_t expected_bitrate_drop_delta,
    int64_t receiver_clock_offset_change_ms) {
  const int kFramerate = 30;
  const int kStartBitrate = 900e3;
  const int kMinExpectedBitrate = 800e3;
  const int kMaxExpectedBitrate = 1100e3;
  const uint32_t kInitialCapacityBps = 1000e3;
  const uint32_t kReducedCapacityBps = 500e3;

  int steady_state_time = 0;
  if (number_of_streams <= 1) {
    steady_state_time = 10;
    AddDefaultStream();
  } else {
    steady_state_time = 10 * number_of_streams;
    int bitrate_sum = 0;
    int kBitrateDenom = number_of_streams * (number_of_streams - 1);
    for (int i = 0; i < number_of_streams; i++) {
      // First stream gets half available bitrate, while the rest share the
      // remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
      int bitrate = kStartBitrate / 2;
      if (i > 0) {
        bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
      }
      stream_generator_->AddStream(new test::RtpStream(kFramerate, bitrate));
      bitrate_sum += bitrate;
    }
    ASSERT_EQ(bitrate_sum, kStartBitrate);
  }

  // Run in steady state to make the estimator converge.
  stream_generator_->set_capacity_bps(kInitialCapacityBps);
  uint32_t bitrate_bps = SteadyStateRun(
      kDefaultSsrc, steady_state_time * kFramerate, kStartBitrate,
      kMinExpectedBitrate, kMaxExpectedBitrate, kInitialCapacityBps);
  EXPECT_NEAR(kInitialCapacityBps, bitrate_bps, 180000u);
  bitrate_observer_.Reset();

  // Add an offset to make sure the BWE can handle it.
  arrival_time_offset_ms_ += receiver_clock_offset_change_ms;

  // Reduce the capacity and verify the decrease time.
  stream_generator_->set_capacity_bps(kReducedCapacityBps);
  int64_t overuse_start_time = clock_.TimeInMilliseconds();
  int64_t bitrate_drop_time = -1;
  for (int i = 0; i < 100 * number_of_streams; ++i) {
    GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
    if (bitrate_drop_time == -1 &&
        bitrate_observer_.latest_bitrate() <= kReducedCapacityBps) {
      bitrate_drop_time = clock_.TimeInMilliseconds();
    }
    if (bitrate_observer_.updated())
      bitrate_bps = bitrate_observer_.latest_bitrate();
  }

  EXPECT_NEAR(expected_bitrate_drop_delta,
              bitrate_drop_time - overuse_start_time, 33);
}

void DelayBasedBweTest::TestTimestampGroupingTestHelper() {
  const int kFramerate = 50;  // 50 fps to avoid rounding errors.
  const int kFrameIntervalMs = 1000 / kFramerate;
  int64_t send_time_ms = 0;
  // Initial set of frames to increase the bitrate. 6 seconds to have enough
  // time for the first estimate to be generated and for Process() to be called.
  for (int i = 0; i <= 6 * kFramerate; ++i) {
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, 1000);

    clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
    send_time_ms += kFrameIntervalMs;
  }
  EXPECT_TRUE(bitrate_observer_.updated());
  EXPECT_GE(bitrate_observer_.latest_bitrate(), 400000u);

  // Insert batches of frames which were sent very close in time. Also simulate
  // capacity over-use to see that we back off correctly.
  const int kTimestampGroupLength = 15;
  for (int i = 0; i < 100; ++i) {
    for (int j = 0; j < kTimestampGroupLength; ++j) {
      // Insert |kTimestampGroupLength| frames with just 1 timestamp ticks in
      // between. Should be treated as part of the same group by the estimator.
      IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, 100);
      clock_.AdvanceTimeMilliseconds(kFrameIntervalMs / kTimestampGroupLength);
      send_time_ms += 1;
    }
    // Increase time until next batch to simulate over-use.
    clock_.AdvanceTimeMilliseconds(10);
    send_time_ms += kFrameIntervalMs - kTimestampGroupLength;
  }
  EXPECT_TRUE(bitrate_observer_.updated());
  // Should have reduced the estimate.
  EXPECT_LT(bitrate_observer_.latest_bitrate(), 400000u);
}

void DelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
  const int kFramerate = 100;
  const int kFrameIntervalMs = 1000 / kFramerate;
  int64_t send_time_ms = 0;

  for (size_t i = 0; i < 3000; ++i) {
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, 1000);
    clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
    send_time_ms += kFrameIntervalMs;
  }
  DataRate bitrate_before = DataRate::Zero();
  std::vector<uint32_t> ssrcs;
  bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_before);

  clock_.AdvanceTimeMilliseconds(silence_time_s * 1000);
  send_time_ms += silence_time_s * 1000;

  for (size_t i = 0; i < 24; ++i) {
    IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms, 1000);
    clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
    send_time_ms += kFrameIntervalMs;
  }
  DataRate bitrate_after = DataRate::Zero();
  bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
  EXPECT_LT(bitrate_after, bitrate_before);
}
}  // namespace webrtc
