// Copyright (c) 2019 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 "quiche/quic/core/batch_writer/quic_batch_writer_buffer.h"

#include <memory>
#include <string>

#include "quiche/quic/core/quic_constants.h"
#include "quiche/quic/platform/api/quic_ip_address.h"
#include "quiche/quic/platform/api/quic_socket_address.h"
#include "quiche/quic/platform/api/quic_test.h"

namespace quic {
namespace test {
namespace {

class QUICHE_EXPORT TestQuicBatchWriterBuffer : public QuicBatchWriterBuffer {
 public:
  using QuicBatchWriterBuffer::buffer_;
  using QuicBatchWriterBuffer::buffered_writes_;
};

static const size_t kBatchBufferSize = QuicBatchWriterBuffer::kBufferSize;

class QuicBatchWriterBufferTest : public QuicTest {
 public:
  QuicBatchWriterBufferTest() { SwitchToNewBuffer(); }

  void SwitchToNewBuffer() {
    batch_buffer_ = std::make_unique<TestQuicBatchWriterBuffer>();
  }

  // Fill packet_buffer_ with kMaxOutgoingPacketSize bytes of |c|s.
  char* FillPacketBuffer(char c) {
    return FillPacketBuffer(c, packet_buffer_, kMaxOutgoingPacketSize);
  }

  // Fill |packet_buffer| with kMaxOutgoingPacketSize bytes of |c|s.
  char* FillPacketBuffer(char c, char* packet_buffer) {
    return FillPacketBuffer(c, packet_buffer, kMaxOutgoingPacketSize);
  }

  // Fill |packet_buffer| with |buf_len| bytes of |c|s.
  char* FillPacketBuffer(char c, char* packet_buffer, size_t buf_len) {
    memset(packet_buffer, c, buf_len);
    return packet_buffer;
  }

  void CheckBufferedWriteContent(int buffered_write_index, char buffer_content,
                                 size_t buf_len, const QuicIpAddress& self_addr,
                                 const QuicSocketAddress& peer_addr,
                                 const PerPacketOptions* /*options*/,
                                 const QuicPacketWriterParams& params) {
    const BufferedWrite& buffered_write =
        batch_buffer_->buffered_writes()[buffered_write_index];
    EXPECT_EQ(buf_len, buffered_write.buf_len);
    for (size_t i = 0; i < buf_len; ++i) {
      EXPECT_EQ(buffer_content, buffered_write.buffer[i]);
      if (buffer_content != buffered_write.buffer[i]) {
        break;
      }
    }
    EXPECT_EQ(self_addr, buffered_write.self_address);
    EXPECT_EQ(peer_addr, buffered_write.peer_address);
    EXPECT_EQ(params.release_time_delay,
              buffered_write.params.release_time_delay);
  }

 protected:
  std::unique_ptr<TestQuicBatchWriterBuffer> batch_buffer_;
  QuicIpAddress self_addr_;
  QuicSocketAddress peer_addr_;
  uint64_t release_time_ = 0;
  char packet_buffer_[kMaxOutgoingPacketSize];
};

class BufferSizeSequence {
 public:
  explicit BufferSizeSequence(
      std::vector<std::pair<std::vector<size_t>, size_t>> stages)
      : stages_(std::move(stages)),
        total_buf_len_(0),
        stage_index_(0),
        sequence_index_(0) {}

  size_t Next() {
    const std::vector<size_t>& seq = stages_[stage_index_].first;
    size_t buf_len = seq[sequence_index_++ % seq.size()];
    total_buf_len_ += buf_len;
    if (stages_[stage_index_].second <= total_buf_len_) {
      stage_index_ = std::min(stage_index_ + 1, stages_.size() - 1);
    }
    return buf_len;
  }

 private:
  const std::vector<std::pair<std::vector<size_t>, size_t>> stages_;
  size_t total_buf_len_;
  size_t stage_index_;
  size_t sequence_index_;
};

// Test in-place pushes. A in-place push is a push with a buffer address that is
// equal to the result of GetNextWriteLocation().
TEST_F(QuicBatchWriterBufferTest, InPlacePushes) {
  std::vector<BufferSizeSequence> buffer_size_sequences = {
      // Push large writes until the buffer is near full, then switch to 1-byte
      // writes. This covers the edge cases when detecting insufficient buffer.
      BufferSizeSequence({{{1350}, kBatchBufferSize - 3000}, {{1}, 1000000}}),
      // A sequence that looks real.
      BufferSizeSequence({{{1, 39, 97, 150, 1350, 1350, 1350, 1350}, 1000000}}),
  };

  for (auto& buffer_size_sequence : buffer_size_sequences) {
    SwitchToNewBuffer();
    int64_t num_push_failures = 0;

    while (batch_buffer_->SizeInUse() < kBatchBufferSize) {
      size_t buf_len = buffer_size_sequence.Next();
      const bool has_enough_space =
          (kBatchBufferSize - batch_buffer_->SizeInUse() >=
           kMaxOutgoingPacketSize);

      char* buffer = batch_buffer_->GetNextWriteLocation();

      if (has_enough_space) {
        EXPECT_EQ(batch_buffer_->buffer_ + batch_buffer_->SizeInUse(), buffer);
      } else {
        EXPECT_EQ(nullptr, buffer);
      }

      SCOPED_TRACE(testing::Message()
                   << "Before Push: buf_len=" << buf_len
                   << ", has_enough_space=" << has_enough_space
                   << ", batch_buffer=" << batch_buffer_->DebugString());

      auto push_result = batch_buffer_->PushBufferedWrite(
          buffer, buf_len, self_addr_, peer_addr_, nullptr,
          QuicPacketWriterParams(), release_time_);
      if (!push_result.succeeded) {
        ++num_push_failures;
      }
      EXPECT_EQ(has_enough_space, push_result.succeeded);
      EXPECT_FALSE(push_result.buffer_copied);
      if (!has_enough_space) {
        break;
      }
    }
    // Expect one and only one failure from the final push operation.
    EXPECT_EQ(1, num_push_failures);
  }
}

// Test some in-place pushes mixed with pushes with external buffers.
TEST_F(QuicBatchWriterBufferTest, MixedPushes) {
  // First, a in-place push.
  char* buffer = batch_buffer_->GetNextWriteLocation();
  QuicPacketWriterParams params;
  auto push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('A', buffer), kDefaultMaxPacketSize, self_addr_,
      peer_addr_, nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_FALSE(push_result.buffer_copied);
  CheckBufferedWriteContent(0, 'A', kDefaultMaxPacketSize, self_addr_,
                            peer_addr_, nullptr, params);

  // Then a push with external buffer.
  push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('B'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
      nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_TRUE(push_result.buffer_copied);
  CheckBufferedWriteContent(1, 'B', kDefaultMaxPacketSize, self_addr_,
                            peer_addr_, nullptr, params);

  // Then another in-place push.
  buffer = batch_buffer_->GetNextWriteLocation();
  push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('C', buffer), kDefaultMaxPacketSize, self_addr_,
      peer_addr_, nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_FALSE(push_result.buffer_copied);
  CheckBufferedWriteContent(2, 'C', kDefaultMaxPacketSize, self_addr_,
                            peer_addr_, nullptr, params);

  // Then another push with external buffer.
  push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('D'), kDefaultMaxPacketSize, self_addr_, peer_addr_,
      nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_TRUE(push_result.buffer_copied);
  CheckBufferedWriteContent(3, 'D', kDefaultMaxPacketSize, self_addr_,
                            peer_addr_, nullptr, params);
}

TEST_F(QuicBatchWriterBufferTest, PopAll) {
  const int kNumBufferedWrites = 10;
  QuicPacketWriterParams params;
  for (int i = 0; i < kNumBufferedWrites; ++i) {
    EXPECT_TRUE(batch_buffer_
                    ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
                                        self_addr_, peer_addr_, nullptr, params,
                                        release_time_)
                    .succeeded);
  }
  EXPECT_EQ(kNumBufferedWrites,
            static_cast<int>(batch_buffer_->buffered_writes().size()));

  auto pop_result = batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
  EXPECT_EQ(0u, batch_buffer_->buffered_writes().size());
  EXPECT_EQ(kNumBufferedWrites, pop_result.num_buffers_popped);
  EXPECT_FALSE(pop_result.moved_remaining_buffers);
}

TEST_F(QuicBatchWriterBufferTest, PopPartial) {
  const int kNumBufferedWrites = 10;
  QuicPacketWriterParams params;
  for (int i = 0; i < kNumBufferedWrites; ++i) {
    EXPECT_TRUE(batch_buffer_
                    ->PushBufferedWrite(
                        FillPacketBuffer('A' + i), kDefaultMaxPacketSize - i,
                        self_addr_, peer_addr_, nullptr, params, release_time_)
                    .succeeded);
  }

  for (size_t i = 0;
       i < kNumBufferedWrites && !batch_buffer_->buffered_writes().empty();
       ++i) {
    const size_t size_before_pop = batch_buffer_->buffered_writes().size();
    const size_t expect_size_after_pop =
        size_before_pop < i ? 0 : size_before_pop - i;
    batch_buffer_->PopBufferedWrite(i);
    ASSERT_EQ(expect_size_after_pop, batch_buffer_->buffered_writes().size());
    const char first_write_content =
        'A' + kNumBufferedWrites - expect_size_after_pop;
    const size_t first_write_len =
        kDefaultMaxPacketSize - kNumBufferedWrites + expect_size_after_pop;
    for (size_t j = 0; j < expect_size_after_pop; ++j) {
      CheckBufferedWriteContent(j, first_write_content + j, first_write_len - j,
                                self_addr_, peer_addr_, nullptr, params);
    }
  }
}

TEST_F(QuicBatchWriterBufferTest, InPlacePushWithPops) {
  // First, a in-place push.
  char* buffer = batch_buffer_->GetNextWriteLocation();
  const size_t first_packet_len = 2;
  QuicPacketWriterParams params;
  auto push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('A', buffer, first_packet_len), first_packet_len,
      self_addr_, peer_addr_, nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_FALSE(push_result.buffer_copied);
  CheckBufferedWriteContent(0, 'A', first_packet_len, self_addr_, peer_addr_,
                            nullptr, params);

  // Simulate the case where the writer wants to do another in-place push, but
  // can't do so because it can't be batched with the first buffer.
  buffer = batch_buffer_->GetNextWriteLocation();
  const size_t second_packet_len = 1350;

  // Flush the first buffer.
  auto pop_result = batch_buffer_->PopBufferedWrite(1);
  EXPECT_EQ(1, pop_result.num_buffers_popped);
  EXPECT_FALSE(pop_result.moved_remaining_buffers);

  // Now the second push.
  push_result = batch_buffer_->PushBufferedWrite(
      FillPacketBuffer('B', buffer, second_packet_len), second_packet_len,
      self_addr_, peer_addr_, nullptr, params, release_time_);
  EXPECT_TRUE(push_result.succeeded);
  EXPECT_TRUE(push_result.buffer_copied);
  CheckBufferedWriteContent(0, 'B', second_packet_len, self_addr_, peer_addr_,
                            nullptr, params);
}

TEST_F(QuicBatchWriterBufferTest, BatchID) {
  const int kNumBufferedWrites = 10;
  QuicPacketWriterParams params;
  auto first_push_result = batch_buffer_->PushBufferedWrite(
      packet_buffer_, kDefaultMaxPacketSize, self_addr_, peer_addr_, nullptr,
      params, release_time_);
  ASSERT_TRUE(first_push_result.succeeded);
  ASSERT_NE(first_push_result.batch_id, 0);
  for (int i = 1; i < kNumBufferedWrites; ++i) {
    EXPECT_EQ(batch_buffer_
                  ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize,
                                      self_addr_, peer_addr_, nullptr, params,
                                      release_time_)
                  .batch_id,
              first_push_result.batch_id);
  }

  batch_buffer_->PopBufferedWrite(kNumBufferedWrites);
  EXPECT_TRUE(batch_buffer_->buffered_writes().empty());

  EXPECT_NE(
      batch_buffer_
          ->PushBufferedWrite(packet_buffer_, kDefaultMaxPacketSize, self_addr_,
                              peer_addr_, nullptr, params, release_time_)
          .batch_id,
      first_push_result.batch_id);
}

}  // namespace
}  // namespace test
}  // namespace quic
