// Copyright (c) 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/third_party/quiche/src/quic/quartc/test/quartc_data_source.h"

#include <vector>

#include "net/third_party/quiche/src/quic/platform/api/quic_test.h"
#include "net/third_party/quiche/src/quic/test_tools/simulator/simulator.h"

namespace quic {
namespace test {
namespace {

class FakeDelegate : public QuartcDataSource::Delegate {
 public:
  void OnDataProduced(const char* data, size_t length) override;

  const std::vector<ParsedQuartcDataFrame>& frames() { return frames_; }

 private:
  std::vector<ParsedQuartcDataFrame> frames_;
};

void FakeDelegate::OnDataProduced(const char* data, size_t length) {
  ParsedQuartcDataFrame frame;
  QuicStringPiece message(data, length);
  if (ParsedQuartcDataFrame::Parse(message, &frame)) {
    frames_.push_back(frame);
  } else {
    QUIC_LOG(FATAL) << "Data source produced a frame it can't parse: "
                    << message;
  }
}

class QuartcDataSourceTest : public QuicTest {
 protected:
  QuartcDataSourceTest() : simulator_() {}

  simulator::Simulator simulator_;
  FakeDelegate delegate_;

  std::unique_ptr<QuartcDataSource> source_;
};

TEST_F(QuartcDataSourceTest, ProducesFrameEveryInterval) {
  QuartcDataSource::Config config;
  config.frame_interval = QuicTime::Delta::FromMilliseconds(20);
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));
  source_->SetEnabled(true);

  simulator_.RunFor(config.frame_interval);
  EXPECT_EQ(delegate_.frames().size(), 1u);

  simulator_.RunFor(config.frame_interval);
  EXPECT_EQ(delegate_.frames().size(), 2u);

  simulator_.RunFor(config.frame_interval * 20);
  EXPECT_EQ(delegate_.frames().size(), 22u);
}

TEST_F(QuartcDataSourceTest, DoesNotProduceFramesUntilEnabled) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));

  simulator_.RunFor(config.frame_interval * 20);
  EXPECT_EQ(delegate_.frames().size(), 0u);

  // The first frame is produced immediately (but asynchronously) upon enabling
  // the source.
  source_->SetEnabled(true);
  simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1));
  EXPECT_EQ(delegate_.frames().size(), 1u);
}

TEST_F(QuartcDataSourceTest, DisableAndEnable) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));

  source_->SetEnabled(true);
  simulator_.RunFor(config.frame_interval * 20);
  EXPECT_EQ(delegate_.frames().size(), 20u);

  // No new frames while the source is disabled.
  source_->SetEnabled(false);
  simulator_.RunFor(config.frame_interval * 20);
  EXPECT_EQ(delegate_.frames().size(), 20u);

  // The first frame is produced immediately (but asynchronously) upon enabling
  // the source.
  source_->SetEnabled(true);
  simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1));
  ASSERT_EQ(delegate_.frames().size(), 21u);

  // The first frame after a pause should be no larger than previous frames.
  EXPECT_EQ(delegate_.frames()[0].payload.size(),
            delegate_.frames()[20].payload.size());

  // The first frame after the pause should have a much later timestamp.
  // Note that the previous frame (19) happens at the *start* of the 20th
  // interval.  Frame 20 would normally happen one interval later, but we've
  // delayed it by an extra 20 intervals (for a total of 21 intervals later).
  EXPECT_EQ(delegate_.frames()[20].send_time - delegate_.frames()[19].send_time,
            21 * config.frame_interval);
}

TEST_F(QuartcDataSourceTest, EnablingTwiceDoesNotChangeSchedule) {
  QuartcDataSource::Config config;
  config.frame_interval = QuicTime::Delta::FromMilliseconds(20);

  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));

  // The first frame is produced immediately (but asynchronously) upon enabling
  // the source.
  source_->SetEnabled(true);
  simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1));
  EXPECT_EQ(delegate_.frames().size(), 1u);

  // Enabling the source again does not re-schedule the alarm.
  source_->SetEnabled(true);
  simulator_.RunFor(QuicTime::Delta::FromMicroseconds(1));
  EXPECT_EQ(delegate_.frames().size(), 1u);

  // The second frame is sent at the expected interval after the first.
  ASSERT_TRUE(
      simulator_.RunUntil([this] { return delegate_.frames().size() == 2; }));

  EXPECT_EQ(delegate_.frames()[1].send_time - delegate_.frames()[0].send_time,
            config.frame_interval);
}

TEST_F(QuartcDataSourceTest, ProducesFramesWithConfiguredSourceId) {
  QuartcDataSource::Config config;
  config.id = 7;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));
  source_->SetEnabled(true);
  simulator_.RunFor(config.frame_interval);

  ASSERT_EQ(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].source_id, config.id);
}

TEST_F(QuartcDataSourceTest, ProducesFramesAtAllocatedBandwidth) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  constexpr QuicByteCount bytes_per_frame = 1000;
  source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta(
      bytes_per_frame, config.frame_interval));
  source_->SetEnabled(true);
  simulator_.RunFor(config.frame_interval);

  ASSERT_EQ(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(),
            bytes_per_frame - kDataFrameHeaderSize);
  EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame);
}

TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenNotEnoughBandwidth) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  // Allocate less bandwidth than the source requires for its header.
  source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta(
      kDataFrameHeaderSize - 10, config.frame_interval));
  source_->SetEnabled(true);

  QuicTime start_time = simulator_.GetClock()->Now();
  simulator_.RunFor(config.frame_interval);

  ASSERT_EQ(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(), 0u);
  EXPECT_EQ(delegate_.frames()[0].size, kDataFrameHeaderSize);

  // Header fields are still present and parseable.
  EXPECT_EQ(delegate_.frames()[0].source_id, 0);
  EXPECT_EQ(delegate_.frames()[0].sequence_number, 0);
  EXPECT_EQ(delegate_.frames()[0].send_time, start_time);
}

TEST_F(QuartcDataSourceTest, ProducesSequenceNumbers) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));
  source_->SetEnabled(true);

  simulator_.RunFor(config.frame_interval * 20);

  ASSERT_EQ(delegate_.frames().size(), 20u);
  for (int i = 0; i < 20; ++i) {
    EXPECT_EQ(delegate_.frames()[i].sequence_number, i);
  }
}

TEST_F(QuartcDataSourceTest, ProducesSendTimes) {
  QuartcDataSource::Config config;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(1000, config.frame_interval));
  source_->SetEnabled(true);

  simulator_.RunFor(config.frame_interval * 20);

  ASSERT_EQ(delegate_.frames().size(), 20u);
  QuicTime first_send_time = delegate_.frames()[0].send_time;
  for (int i = 1; i < 20; ++i) {
    EXPECT_EQ(delegate_.frames()[i].send_time,
              first_send_time + i * config.frame_interval);
  }
}

TEST_F(QuartcDataSourceTest, AllocateClampsToMin) {
  QuartcDataSource::Config config;
  config.min_bandwidth = QuicBandwidth::FromBitsPerSecond(8000);
  config.frame_interval = QuicTime::Delta::FromMilliseconds(100);
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  // When allocating less than the minimum, there is nothing left over.
  EXPECT_EQ(source_->AllocateBandwidth(QuicBandwidth::FromBitsPerSecond(6000)),
            QuicBandwidth::Zero());

  source_->SetEnabled(true);
  simulator_.RunFor(config.frame_interval);

  // The frames produced use min_bandwidth instead of the lower allocation.
  QuicByteCount bytes_per_frame =
      config.min_bandwidth.ToBytesPerPeriod(config.frame_interval);
  ASSERT_EQ(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(),
            bytes_per_frame - kDataFrameHeaderSize);
  EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame);
}

TEST_F(QuartcDataSourceTest, AllocateClampsToMax) {
  QuartcDataSource::Config config;
  config.max_bandwidth = QuicBandwidth::FromBitsPerSecond(8000);
  config.frame_interval = QuicTime::Delta::FromMilliseconds(100);
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  // When allocating more than the maximum, the excess is returned.
  EXPECT_EQ(source_->AllocateBandwidth(QuicBandwidth::FromBitsPerSecond(10000)),
            QuicBandwidth::FromBitsPerSecond(2000));

  source_->SetEnabled(true);
  simulator_.RunFor(config.frame_interval);

  // The frames produced use max_bandwidth instead of the higher allocation.
  QuicByteCount bytes_per_frame =
      config.max_bandwidth.ToBytesPerPeriod(config.frame_interval);
  ASSERT_EQ(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(),
            bytes_per_frame - kDataFrameHeaderSize);
  EXPECT_EQ(delegate_.frames()[0].size, bytes_per_frame);
}

TEST_F(QuartcDataSourceTest, MaxFrameSize) {
  constexpr QuicByteCount bytes_per_frame = 1000;
  QuartcDataSource::Config config;
  config.max_frame_size = bytes_per_frame;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  // Allocate enough bandwidth for more than one frame per interval.
  source_->AllocateBandwidth(QuicBandwidth::FromBytesAndTimeDelta(
      3 * bytes_per_frame, config.frame_interval));
  source_->SetEnabled(true);

  QuicTime start_time = simulator_.GetClock()->Now();
  simulator_.RunFor(config.frame_interval);

  // Since there's enough bandwidth for three frames per interval, that's what
  // the source should generate.
  EXPECT_EQ(delegate_.frames().size(), 3u);
  int i = 0;
  for (const auto& frame : delegate_.frames()) {
    // Each of the frames should start with a header that can be parsed.
    // Each gets the same timestamp, but a different sequence number.
    EXPECT_EQ(frame.source_id, config.id);
    EXPECT_EQ(frame.sequence_number, i++);
    EXPECT_EQ(frame.send_time, start_time);

    // Each of the frames should have the configured maximum size.
    EXPECT_EQ(frame.payload.size(), bytes_per_frame - kDataFrameHeaderSize);
    EXPECT_EQ(frame.size, bytes_per_frame);
  }
}

TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenMaxFrameSizeTooSmall) {
  QuartcDataSource::Config config;
  config.max_frame_size = kDataFrameHeaderSize - 1;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(200, config.frame_interval));
  source_->SetEnabled(true);

  QuicTime start_time = simulator_.GetClock()->Now();
  simulator_.RunFor(config.frame_interval);

  ASSERT_GE(delegate_.frames().size(), 1u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(), 0u);
  EXPECT_EQ(delegate_.frames()[0].size, kDataFrameHeaderSize);

  // Header fields are still present and parseable.
  EXPECT_EQ(delegate_.frames()[0].source_id, 0);
  EXPECT_EQ(delegate_.frames()[0].sequence_number, 0);
  EXPECT_EQ(delegate_.frames()[0].send_time, start_time);
}

TEST_F(QuartcDataSourceTest, ProducesParseableHeaderWhenLeftoverSizeTooSmall) {
  QuartcDataSource::Config config;
  config.max_frame_size = 200;
  source_ = std::make_unique<QuartcDataSource>(
      simulator_.GetClock(), simulator_.GetAlarmFactory(),
      simulator_.GetRandomGenerator(), config, &delegate_);

  // Allocate enough bandwidth to send a 200-byte frame and a 1-byte frame.
  source_->AllocateBandwidth(
      QuicBandwidth::FromBytesAndTimeDelta(201, config.frame_interval));
  source_->SetEnabled(true);

  QuicTime start_time = simulator_.GetClock()->Now();
  simulator_.RunFor(config.frame_interval);

  ASSERT_EQ(delegate_.frames().size(), 2u);
  EXPECT_EQ(delegate_.frames()[0].payload.size(), 200u - kDataFrameHeaderSize);
  EXPECT_EQ(delegate_.frames()[0].size, 200u);

  // The second frame, using the 1 leftover byte from the first, rounds up to
  // the minimum frame size (just the header and no payload).
  EXPECT_EQ(delegate_.frames()[1].payload.size(), 0u);
  EXPECT_EQ(delegate_.frames()[1].size, kDataFrameHeaderSize);

  // Header fields are still present and parseable.
  EXPECT_EQ(delegate_.frames()[1].source_id, 0);
  EXPECT_EQ(delegate_.frames()[1].sequence_number, 1);
  EXPECT_EQ(delegate_.frames()[1].send_time, start_time);
}

}  // namespace
}  // namespace test
}  // namespace quic
