// 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 "quic/test_tools/quic_stream_sequencer_buffer_peer.h"
#include <cstddef>

#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_logging.h"
#include "quic/platform/api/quic_test.h"
#include "quic/test_tools/quic_test_utils.h"

using BufferBlock = quic::QuicStreamSequencerBuffer::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;
  std::string error_details;
  EXPECT_THAT(buffer_->Readv(&dest, 1, &bytes_read, &error_details),
              IsQuicNoError());
  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 = current_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_->max_blocks_count_ * kBlockSizeBytes) &&
      (buffer_->max_buffer_capacity_bytes_ >
       (buffer_->max_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::max_blocks_count() {
  return buffer_->max_blocks_count_;
}

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

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

}  // namespace test
}  // namespace quic
