// 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 "net/third_party/quiche/src/quic/core/quic_data_reader.h"
#include "net/third_party/quiche/src/quic/core/quic_data_writer.h"

namespace quic {
namespace test {

namespace {

class SendAlarmDelegate : public QuicAlarm::Delegate {
 public:
  explicit SendAlarmDelegate(QuartcDataSource* source) : source_(source) {}

  void OnAlarm() override { source_->OnSendAlarm(); }

 private:
  QuartcDataSource* source_;
};

}  // namespace

bool ParsedQuartcDataFrame::Parse(QuicStringPiece data,
                                  ParsedQuartcDataFrame* out) {
  QuicDataReader reader(data.data(), data.size());

  uint32_t source_id;
  if (!reader.ReadUInt32(&source_id)) {
    return false;
  }

  uint64_t sequence_number;
  if (!reader.ReadUInt64(&sequence_number)) {
    return false;
  }

  uint64_t time_bits;
  if (!reader.ReadUInt64(&time_bits)) {
    return false;
  }
  QuicStringPiece payload = reader.ReadRemainingPayload();

  out->source_id = source_id;
  out->sequence_number = sequence_number;
  out->send_time =
      QuicTime::Zero() + QuicTime::Delta::FromMicroseconds(time_bits);
  out->payload = std::string(payload.data(), payload.size());

  return true;
}

QuartcDataSource::QuartcDataSource(const QuicClock* clock,
                                   QuicAlarmFactory* alarm_factory,
                                   QuicRandom* random,
                                   const Config& config,
                                   Delegate* delegate)
    : clock_(clock),
      alarm_factory_(alarm_factory),
      random_(random),
      config_(config),
      delegate_(delegate),
      send_alarm_(alarm_factory_->CreateAlarm(new SendAlarmDelegate(this))),
      sequence_number_(0),
      allocated_bandwidth_(config_.min_bandwidth),
      last_send_time_(QuicTime::Zero()) {}

void QuartcDataSource::OnSendAlarm() {
  QuicTime now = clock_->Now();
  QuicTime::Delta time_since_last_send(QuicTime::Delta::Zero());
  if (last_send_time_.IsInitialized()) {
    // If previous frames have been sent, use the actual time since the last
    // send to compute the frame size.
    time_since_last_send = now - last_send_time_;
  } else {
    // For the first frame, use the configured frame interval.
    time_since_last_send = config_.frame_interval;
  }

  QuicByteCount bytes =
      std::max(kDataFrameHeaderSize,
               allocated_bandwidth_.ToBytesPerPeriod(time_since_last_send));
  while (config_.max_frame_size >= kDataFrameHeaderSize &&
         bytes > config_.max_frame_size) {
    GenerateFrame(config_.max_frame_size, now);
    bytes -= config_.max_frame_size;
  }
  GenerateFrame(bytes, now);

  // Reset alarm.
  last_send_time_ = now;
  send_alarm_->Set(now + config_.frame_interval);
}

QuicBandwidth QuartcDataSource::AllocateBandwidth(QuicBandwidth bandwidth) {
  allocated_bandwidth_ = std::max(config_.min_bandwidth,
                                  std::min(bandwidth, config_.max_bandwidth));
  return std::max(bandwidth - allocated_bandwidth_, QuicBandwidth::Zero());
}

bool QuartcDataSource::Enabled() {
  return send_alarm_->IsSet();
}

void QuartcDataSource::SetEnabled(bool value) {
  if (value) {
    send_alarm_->Set(clock_->Now());
  } else {
    send_alarm_->Cancel();

    // Reset the last send time.  When re-enabled, the data source should
    // produce a frame of approximately the right size for its current
    // bandwidth allocation and frame interval, not a huge frame accounting for
    // all the time since it was disabled.
    last_send_time_ = QuicTime::Zero();
  }
}

void QuartcDataSource::GenerateFrame(QuicByteCount frame_size, QuicTime now) {
  if (buffer_.size() < frame_size) {
    buffer_.resize(frame_size);
  }

  // Generate data.
  QuicDataWriter writer(frame_size, buffer_.data());
  writer.WriteUInt32(config_.id);
  writer.WriteUInt64(sequence_number_++);
  writer.WriteUInt64((now - QuicTime::Zero()).ToMicroseconds());
  writer.WriteRandomBytes(random_, writer.remaining());

  delegate_->OnDataProduced(writer.data(), writer.length());
}

}  // namespace test
}  // namespace quic
