// 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/quic/quartc/quartc_packet_writer.h"

namespace quic {

std::unique_ptr<PerPacketOptions> QuartcPerPacketOptions::Clone() const {
  return QuicMakeUnique<QuartcPerPacketOptions>(*this);
}

QuartcPacketWriter::QuartcPacketWriter(QuartcPacketTransport* packet_transport,
                                       QuicByteCount max_packet_size)
    : packet_transport_(packet_transport), max_packet_size_(max_packet_size) {}

WriteResult QuartcPacketWriter::WritePacket(
    const char* buffer,
    size_t buf_len,
    const QuicIpAddress& self_address,
    const QuicSocketAddress& peer_address,
    PerPacketOptions* options) {
  DCHECK(packet_transport_);

  QuartcPacketTransport::PacketInfo info;
  QuartcPerPacketOptions* quartc_options =
      static_cast<QuartcPerPacketOptions*>(options);
  if (quartc_options && quartc_options->connection) {
    info.packet_number =
        quartc_options->connection->packet_generator().packet_number();
  }
  int bytes_written = packet_transport_->Write(buffer, buf_len, info);
  if (bytes_written <= 0) {
    writable_ = false;
    return WriteResult(WRITE_STATUS_BLOCKED, EWOULDBLOCK);
  }
  return WriteResult(WRITE_STATUS_OK, bytes_written);
}

bool QuartcPacketWriter::IsWriteBlocked() const {
  return !writable_;
}

QuicByteCount QuartcPacketWriter::GetMaxPacketSize(
    const QuicSocketAddress& peer_address) const {
  return max_packet_size_;
}

void QuartcPacketWriter::SetWritable() {
  writable_ = true;
}

bool QuartcPacketWriter::SupportsReleaseTime() const {
  return false;
}

bool QuartcPacketWriter::IsBatchMode() const {
  return false;
}

char* QuartcPacketWriter::GetNextWriteLocation(
    const QuicIpAddress& self_address,
    const QuicSocketAddress& peer_address) {
  return nullptr;
}

WriteResult QuartcPacketWriter::Flush() {
  return WriteResult(WRITE_STATUS_OK, 0);
}

void QuartcPacketWriter::SetPacketTransportDelegate(
    QuartcPacketTransport::Delegate* delegate) {
  packet_transport_->SetDelegate(delegate);
}

}  // namespace quic
