// Copyright 2014 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/quic/quic_flow_controller.h"

#include "base/basictypes.h"
#include "net/quic/quic_connection.h"
#include "net/quic/quic_flags.h"
#include "net/quic/quic_protocol.h"

namespace net {

#define ENDPOINT (is_server_ ? "Server: " : " Client: ")

QuicFlowController::QuicFlowController(QuicConnection* connection,
                                       QuicStreamId id,
                                       bool is_server,
                                       uint64 send_window_offset,
                                       uint64 receive_window_offset,
                                       uint64 max_receive_window)
    : connection_(connection),
      id_(id),
      is_enabled_(true),
      is_server_(is_server),
      bytes_consumed_(0),
      highest_received_byte_offset_(0),
      bytes_sent_(0),
      send_window_offset_(send_window_offset),
      receive_window_offset_(receive_window_offset),
      max_receive_window_(max_receive_window),
      last_blocked_send_window_offset_(0) {
  DVLOG(1) << ENDPOINT << "Created flow controller for stream " << id_
           << ", setting initial receive window offset to: "
           << receive_window_offset_
           << ", max receive window to: "
           << max_receive_window_
           << ", setting send window offset to: " << send_window_offset_;
}

void QuicFlowController::AddBytesConsumed(uint64 bytes_consumed) {
  if (!IsEnabled()) {
    return;
  }

  bytes_consumed_ += bytes_consumed;
  DVLOG(1) << ENDPOINT << "Stream " << id_ << " consumed: " << bytes_consumed_;

  MaybeSendWindowUpdate();
}

bool QuicFlowController::UpdateHighestReceivedOffset(uint64 new_offset) {
  if (!IsEnabled()) {
    return false;
  }

  // Only update if offset has increased.
  if (new_offset <= highest_received_byte_offset_) {
    return false;
  }

  DVLOG(1) << ENDPOINT << "Stream " << id_
           << " highest byte offset increased from: "
           << highest_received_byte_offset_ << " to " << new_offset;
  highest_received_byte_offset_ = new_offset;
  return true;
}

void QuicFlowController::AddBytesSent(uint64 bytes_sent) {
  if (!IsEnabled()) {
    return;
  }

  if (bytes_sent_ + bytes_sent > send_window_offset_) {
    LOG(DFATAL) << ENDPOINT << "Stream " << id_ << " Trying to send an extra "
                << bytes_sent << " bytes, when bytes_sent = " << bytes_sent_
                << ", and send_window_offset_ = " << send_window_offset_;
    bytes_sent_ = send_window_offset_;

    // This is an error on our side, close the connection as soon as possible.
    connection_->SendConnectionClose(QUIC_FLOW_CONTROL_SENT_TOO_MUCH_DATA);
    return;
  }

  bytes_sent_ += bytes_sent;
  DVLOG(1) << ENDPOINT << "Stream " << id_ << " sent: " << bytes_sent_;
}

bool QuicFlowController::FlowControlViolation() {
  if (!IsEnabled()) {
    return false;
  }

  if (highest_received_byte_offset_ > receive_window_offset_) {
    LOG(ERROR) << ENDPOINT << "Flow control violation on stream "
               << id_ << ", receive window offset: "
               << receive_window_offset_
               << ", highest received byte offset: "
               << highest_received_byte_offset_;
    return true;
  }
  return false;
}

void QuicFlowController::MaybeSendWindowUpdate() {
  if (!IsEnabled()) {
    return;
  }

  // Send WindowUpdate to increase receive window if
  // (receive window offset - consumed bytes) < (max window / 2).
  // This is behaviour copied from SPDY.
  DCHECK_LT(bytes_consumed_, receive_window_offset_);
  size_t consumed_window = receive_window_offset_ - bytes_consumed_;
  size_t threshold = (max_receive_window_ / 2);

  if (consumed_window < threshold) {
    // Update our receive window.
    receive_window_offset_ += (max_receive_window_ - consumed_window);

    DVLOG(1) << ENDPOINT << "Sending WindowUpdate frame for stream " << id_
             << ", consumed bytes: " << bytes_consumed_
             << ", consumed window: " << consumed_window
             << ", and threshold: " << threshold
             << ", and max recvw: " << max_receive_window_
             << ". New receive window offset is: " << receive_window_offset_;

    // Inform the peer of our new receive window.
    connection_->SendWindowUpdate(id_, receive_window_offset_);
  }
}

void QuicFlowController::MaybeSendBlocked() {
  if (!IsEnabled()) {
    return;
  }

  if (SendWindowSize() == 0 &&
      last_blocked_send_window_offset_ < send_window_offset_) {
    DVLOG(1) << ENDPOINT << "Stream " << id_ << " is flow control blocked. "
             << "Send window: " << SendWindowSize()
             << ", bytes sent: " << bytes_sent_
             << ", send limit: " << send_window_offset_;
    // The entire send_window has been consumed, we are now flow control
    // blocked.
    connection_->SendBlocked(id_);

    // Keep track of when we last sent a BLOCKED frame so that we only send one
    // at a given send offset.
    last_blocked_send_window_offset_ = send_window_offset_;
  }
}

bool QuicFlowController::UpdateSendWindowOffset(uint64 new_send_window_offset) {
  if (!IsEnabled()) {
    return false;
  }

  // Only update if send window has increased.
  if (new_send_window_offset <= send_window_offset_) {
    return false;
  }

  DVLOG(1) << ENDPOINT << "UpdateSendWindowOffset for stream " << id_
           << " with new offset " << new_send_window_offset
           << " current offset: " << send_window_offset_
           << " bytes_sent: " << bytes_sent_;

  const bool blocked = IsBlocked();
  send_window_offset_ = new_send_window_offset;
  return blocked;
}

void QuicFlowController::Disable() {
  is_enabled_ = false;
}

bool QuicFlowController::IsEnabled() const {
  return is_enabled_;
}

bool QuicFlowController::IsBlocked() const {
  return IsEnabled() && SendWindowSize() == 0;
}

uint64 QuicFlowController::SendWindowSize() const {
  if (bytes_sent_ > send_window_offset_) {
    return 0;
  }
  return send_window_offset_ - bytes_sent_;
}

}  // namespace net
