// Copyright 2016 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/test_tools/quic_stream_sequencer_buffer_peer.h"

#include "net/third_party/quic/platform/api/quic_flags.h"
#include "net/third_party/quic/platform/api/quic_logging.h"
#include "net/third_party/quic/platform/api/quic_test.h"

typedef quic::QuicStreamSequencerBuffer::BufferBlock BufferBlock;

static const size_t kBlockSizeBytes =
    quic::QuicStreamSequencerBuffer::kBlockSizeBytes;

namespace quic {
namespace test {

QuicStreamSequencerBufferPeer::QuicStreamSequencerBufferPeer(
    QuicStreamSequencerBuffer* buffer)
    : buffer_(buffer) {}

// Read from this buffer_ into the given destination buffer_ up to the
// size of the destination. Returns the number of bytes read. Reading from
// an empty buffer_->returns 0.
size_t QuicStreamSequencerBufferPeer::Read(char* dest_buffer, size_t size) {
  IOVEC dest;
  dest.iov_base = dest_buffer, dest.iov_len = size;
  size_t bytes_read;
  QuicString error_details;
  EXPECT_EQ(QUIC_NO_ERROR,
            buffer_->Readv(&dest, 1, &bytes_read, &error_details));
  return bytes_read;
}

// If buffer is empty, the blocks_ array must be empty, which means all
// blocks are deallocated.
bool QuicStreamSequencerBufferPeer::CheckEmptyInvariants() {
  return !buffer_->Empty() || IsBlockArrayEmpty();
}

bool QuicStreamSequencerBufferPeer::IsBlockArrayEmpty() {
  if (buffer_->blocks_ == nullptr) {
    return true;
  }

  size_t count = buffer_->blocks_count_;
  for (size_t i = 0; i < count; i++) {
    if (buffer_->blocks_[i] != nullptr) {
      return false;
    }
  }
  return true;
}

bool QuicStreamSequencerBufferPeer::CheckInitialState() {
  EXPECT_TRUE(buffer_->Empty() && buffer_->total_bytes_read_ == 0 &&
              buffer_->num_bytes_buffered_ == 0);
  return CheckBufferInvariants();
}

bool QuicStreamSequencerBufferPeer::CheckBufferInvariants() {
  QuicStreamOffset data_span =
      buffer_->NextExpectedByte() - buffer_->total_bytes_read_;
  bool capacity_sane = data_span <= buffer_->max_buffer_capacity_bytes_ &&
                       data_span >= buffer_->num_bytes_buffered_;
  if (!capacity_sane) {
    QUIC_LOG(ERROR) << "data span is larger than capacity.";
    QUIC_LOG(ERROR) << "total read: " << buffer_->total_bytes_read_
                    << " last byte: " << buffer_->NextExpectedByte();
  }
  bool total_read_sane =
      buffer_->FirstMissingByte() >= buffer_->total_bytes_read_;
  if (!total_read_sane) {
    QUIC_LOG(ERROR) << "read across 1st gap.";
  }
  bool read_offset_sane = buffer_->ReadOffset() < kBlockSizeBytes;
  if (!capacity_sane) {
    QUIC_LOG(ERROR) << "read offset go beyond 1st block";
  }
  bool block_match_capacity = (buffer_->max_buffer_capacity_bytes_ <=
                               buffer_->blocks_count_ * kBlockSizeBytes) &&
                              (buffer_->max_buffer_capacity_bytes_ >
                               (buffer_->blocks_count_ - 1) * kBlockSizeBytes);
  if (!capacity_sane) {
    QUIC_LOG(ERROR) << "block number not match capcaity.";
  }
  bool block_retired_when_empty = CheckEmptyInvariants();
  if (!block_retired_when_empty) {
    QUIC_LOG(ERROR) << "block is not retired after use.";
  }
  return capacity_sane && total_read_sane && read_offset_sane &&
         block_match_capacity && block_retired_when_empty;
}

size_t QuicStreamSequencerBufferPeer::GetInBlockOffset(
    QuicStreamOffset offset) {
  return buffer_->GetInBlockOffset(offset);
}

BufferBlock* QuicStreamSequencerBufferPeer::GetBlock(size_t index) {
  return buffer_->blocks_[index];
}

int QuicStreamSequencerBufferPeer::IntervalSize() {
  if (buffer_->bytes_received_.Empty()) {
    return 1;
  }
  int gap_size = buffer_->bytes_received_.Size() + 1;
  if (buffer_->bytes_received_.Empty()) {
    return gap_size;
  }
  if (buffer_->bytes_received_.begin()->min() == 0) {
    --gap_size;
  }
  if (buffer_->bytes_received_.rbegin()->max() ==
      std::numeric_limits<uint64_t>::max()) {
    --gap_size;
  }
  return gap_size;
}

size_t QuicStreamSequencerBufferPeer::max_buffer_capacity() {
  return buffer_->max_buffer_capacity_bytes_;
}

size_t QuicStreamSequencerBufferPeer::ReadableBytes() {
  return buffer_->ReadableBytes();
}

void QuicStreamSequencerBufferPeer::set_total_bytes_read(
    QuicStreamOffset total_bytes_read) {
  buffer_->total_bytes_read_ = total_bytes_read;
}

void QuicStreamSequencerBufferPeer::AddBytesReceived(QuicStreamOffset offset,
                                                     QuicByteCount length) {
  buffer_->bytes_received_.Add(offset, offset + length);
}

bool QuicStreamSequencerBufferPeer::IsBufferAllocated() {
  return buffer_->blocks_ != nullptr;
}

size_t QuicStreamSequencerBufferPeer::block_count() {
  return buffer_->blocks_count_;
}

const QuicIntervalSet<QuicStreamOffset>&
QuicStreamSequencerBufferPeer::bytes_received() {
  return buffer_->bytes_received_;
}

}  // namespace test
}  // namespace quic
