// 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 "quic/core/quic_stream_send_buffer.h"

#include <string>

#include "absl/strings/string_view.h"
#include "quic/core/quic_data_writer.h"
#include "quic/core/quic_simple_buffer_allocator.h"
#include "quic/core/quic_utils.h"
#include "quic/platform/api/quic_expect_bug.h"
#include "quic/platform/api/quic_flags.h"
#include "quic/platform/api/quic_test.h"
#include "quic/platform/api/quic_test_mem_slice_vector.h"
#include "quic/test_tools/quic_stream_send_buffer_peer.h"
#include "quic/test_tools/quic_test_utils.h"

namespace quic {
namespace test {
namespace {

struct iovec MakeIovec(absl::string_view data) {
  struct iovec iov = {const_cast<char*>(data.data()),
                      static_cast<size_t>(data.size())};
  return iov;
}

class QuicStreamSendBufferTest : public QuicTest {
 public:
  QuicStreamSendBufferTest() : send_buffer_(&allocator_) {
    EXPECT_EQ(0u, send_buffer_.size());
    EXPECT_EQ(0u, send_buffer_.stream_bytes_written());
    EXPECT_EQ(0u, send_buffer_.stream_bytes_outstanding());
    std::string data1(1536, 'a');
    std::string data2 = std::string(256, 'b') + std::string(256, 'c');
    struct iovec iov[2];
    iov[0] = MakeIovec(absl::string_view(data1));
    iov[1] = MakeIovec(absl::string_view(data2));

    QuicBuffer buffer1(&allocator_, 1024);
    memset(buffer1.data(), 'c', buffer1.size());
    QuicMemSlice slice1(std::move(buffer1));
    QuicBuffer buffer2(&allocator_, 768);
    memset(buffer2.data(), 'd', buffer2.size());
    QuicMemSlice slice2(std::move(buffer2));

    // The stream offset should be 0 since nothing is written.
    EXPECT_EQ(0u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));

    // Save all data.
    SetQuicFlag(FLAGS_quic_send_buffer_max_data_slice_size, 1024);
    send_buffer_.SaveStreamData(iov, 2, 0, 2048);
    send_buffer_.SaveMemSlice(std::move(slice1));
    EXPECT_TRUE(slice1.empty());
    send_buffer_.SaveMemSlice(std::move(slice2));
    EXPECT_TRUE(slice2.empty());

    EXPECT_EQ(4u, send_buffer_.size());
    // At this point, the whole buffer looks like:
    // |      a * 1536      |b * 256|         c * 1280        |  d * 768  |
    // |    slice1     |     slice2       |      slice3       |   slice4  |
  }

  void WriteAllData() {
    // Write all data.
    char buf[4000];
    QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
    send_buffer_.WriteStreamData(0, 3840u, &writer);

    send_buffer_.OnStreamDataConsumed(3840u);
    EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
    EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
  }

  SimpleBufferAllocator allocator_;
  QuicStreamSendBuffer send_buffer_;
};

TEST_F(QuicStreamSendBufferTest, CopyDataToBuffer) {
  char buf[4000];
  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);
  std::string copy1(1024, 'a');
  std::string copy2 =
      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
  std::string copy3(1024, 'c');
  std::string copy4(768, 'd');

  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 1024, &writer));
  EXPECT_EQ(copy2, absl::string_view(buf + 1024, 1024));
  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1024, &writer));
  EXPECT_EQ(copy3, absl::string_view(buf + 2048, 1024));
  ASSERT_TRUE(send_buffer_.WriteStreamData(3072, 768, &writer));
  EXPECT_EQ(copy4, absl::string_view(buf + 3072, 768));

  // Test data piece across boundries.
  QuicDataWriter writer2(4000, buf, quiche::HOST_BYTE_ORDER);
  std::string copy5 =
      std::string(536, 'a') + std::string(256, 'b') + std::string(232, 'c');
  ASSERT_TRUE(send_buffer_.WriteStreamData(1000, 1024, &writer2));
  EXPECT_EQ(copy5, absl::string_view(buf, 1024));
  ASSERT_TRUE(send_buffer_.WriteStreamData(2500, 1024, &writer2));
  std::string copy6 = std::string(572, 'c') + std::string(452, 'd');
  EXPECT_EQ(copy6, absl::string_view(buf + 1024, 1024));

  // Invalid data copy.
  QuicDataWriter writer3(4000, buf, quiche::HOST_BYTE_ORDER);
  EXPECT_FALSE(send_buffer_.WriteStreamData(3000, 1024, &writer3));
  EXPECT_QUIC_BUG(send_buffer_.WriteStreamData(0, 4000, &writer3),
                  "Writer fails to write.");

  send_buffer_.OnStreamDataConsumed(3840);
  EXPECT_EQ(3840u, send_buffer_.stream_bytes_written());
  EXPECT_EQ(3840u, send_buffer_.stream_bytes_outstanding());
}

// Regression test for b/143491027.
TEST_F(QuicStreamSendBufferTest,
       WriteStreamDataContainsBothRetransmissionAndNewData) {
  std::string copy1(1024, 'a');
  std::string copy2 =
      std::string(512, 'a') + std::string(256, 'b') + std::string(256, 'c');
  std::string copy3 = std::string(1024, 'c') + std::string(100, 'd');
  char buf[6000];
  QuicDataWriter writer(6000, buf, quiche::HOST_BYTE_ORDER);
  // Write more than one slice.
  EXPECT_EQ(0, QuicStreamSendBufferPeer::write_index(&send_buffer_));
  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
  EXPECT_EQ(copy1, absl::string_view(buf, 1024));
  EXPECT_EQ(1, QuicStreamSendBufferPeer::write_index(&send_buffer_));

  // Retransmit the first frame and also send new data.
  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 2048, &writer));
  EXPECT_EQ(copy1 + copy2, absl::string_view(buf + 1024, 2048));

  // Write new data.
  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 50, &writer));
  EXPECT_EQ(std::string(50, 'c'), absl::string_view(buf + 1024 + 2048, 50));
  EXPECT_EQ(3072u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
  ASSERT_TRUE(send_buffer_.WriteStreamData(2048, 1124, &writer));
  EXPECT_EQ(copy3, absl::string_view(buf + 1024 + 2048 + 50, 1124));
  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
}

TEST_F(QuicStreamSendBufferTest, RemoveStreamFrame) {
  WriteAllData();

  QuicByteCount newly_acked_length;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1024, 1024, &newly_acked_length));
  EXPECT_EQ(1024u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2048, 1024, &newly_acked_length));
  EXPECT_EQ(1024u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
  EXPECT_EQ(1024u, newly_acked_length);

  // Send buffer is cleaned up in order.
  EXPECT_EQ(1u, send_buffer_.size());
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3072, 768, &newly_acked_length));
  EXPECT_EQ(768u, newly_acked_length);
  EXPECT_EQ(0u, send_buffer_.size());
}

TEST_F(QuicStreamSendBufferTest, RemoveStreamFrameAcrossBoundries) {
  WriteAllData();

  QuicByteCount newly_acked_length;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2024, 576, &newly_acked_length));
  EXPECT_EQ(576u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
  EXPECT_EQ(1000u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1000, 1024, &newly_acked_length));
  EXPECT_EQ(1024u, newly_acked_length);
  // Send buffer is cleaned up in order.
  EXPECT_EQ(2u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2600, 1024, &newly_acked_length));
  EXPECT_EQ(1024u, newly_acked_length);
  EXPECT_EQ(1u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(3624, 216, &newly_acked_length));
  EXPECT_EQ(216u, newly_acked_length);
  EXPECT_EQ(0u, send_buffer_.size());
}

TEST_F(QuicStreamSendBufferTest, AckStreamDataMultipleTimes) {
  WriteAllData();
  QuicByteCount newly_acked_length;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(100, 1500, &newly_acked_length));
  EXPECT_EQ(1500u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 500, &newly_acked_length));
  EXPECT_EQ(500u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 2600, &newly_acked_length));
  EXPECT_EQ(600u, newly_acked_length);
  // Send buffer is cleaned up in order.
  EXPECT_EQ(2u, send_buffer_.size());

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2200, 1640, &newly_acked_length));
  EXPECT_EQ(1240u, newly_acked_length);
  EXPECT_EQ(0u, send_buffer_.size());

  EXPECT_FALSE(send_buffer_.OnStreamDataAcked(4000, 100, &newly_acked_length));
}

TEST_F(QuicStreamSendBufferTest, AckStreamDataOutOfOrder) {
  WriteAllData();
  QuicByteCount newly_acked_length;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 1000, &newly_acked_length));
  EXPECT_EQ(1000u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());
  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(1200, 1000, &newly_acked_length));
  EXPECT_EQ(700u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());
  // Slice 2 gets fully acked.
  EXPECT_EQ(2816u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(2000, 1840, &newly_acked_length));
  EXPECT_EQ(1640u, newly_acked_length);
  EXPECT_EQ(4u, send_buffer_.size());
  // Slices 3 and 4 get fully acked.
  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));

  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1000, &newly_acked_length));
  EXPECT_EQ(500u, newly_acked_length);
  EXPECT_EQ(0u, send_buffer_.size());
  EXPECT_EQ(0u, QuicStreamSendBufferPeer::TotalLength(&send_buffer_));
}

TEST_F(QuicStreamSendBufferTest, PendingRetransmission) {
  WriteAllData();
  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 3840));
  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());
  // Lost data [0, 1200).
  send_buffer_.OnStreamDataLost(0, 1200);
  // Lost data [1500, 2000).
  send_buffer_.OnStreamDataLost(1500, 500);
  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());

  EXPECT_EQ(StreamPendingRetransmission(0, 1200),
            send_buffer_.NextPendingRetransmission());
  // Retransmit data [0, 500).
  send_buffer_.OnStreamDataRetransmitted(0, 500);
  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(0, 500));
  EXPECT_EQ(StreamPendingRetransmission(500, 700),
            send_buffer_.NextPendingRetransmission());
  // Ack data [500, 1200).
  QuicByteCount newly_acked_length = 0;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(500, 700, &newly_acked_length));
  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(500, 700));
  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
  EXPECT_EQ(StreamPendingRetransmission(1500, 500),
            send_buffer_.NextPendingRetransmission());
  // Retransmit data [1500, 2000).
  send_buffer_.OnStreamDataRetransmitted(1500, 500);
  EXPECT_FALSE(send_buffer_.HasPendingRetransmission());

  // Lost [200, 800).
  send_buffer_.OnStreamDataLost(200, 600);
  EXPECT_TRUE(send_buffer_.HasPendingRetransmission());
  // Verify [200, 500) is considered as lost, as [500, 800) has been acked.
  EXPECT_EQ(StreamPendingRetransmission(200, 300),
            send_buffer_.NextPendingRetransmission());

  // Verify 0 length data is not outstanding.
  EXPECT_FALSE(send_buffer_.IsStreamDataOutstanding(100, 0));
  // Verify partially acked data is outstanding.
  EXPECT_TRUE(send_buffer_.IsStreamDataOutstanding(400, 800));
}

TEST_F(QuicStreamSendBufferTest, EndOffset) {
  char buf[4000];
  QuicDataWriter writer(4000, buf, quiche::HOST_BYTE_ORDER);

  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
  ASSERT_TRUE(send_buffer_.WriteStreamData(0, 1024, &writer));
  // Last offset we've seen is 1024
  EXPECT_EQ(1024u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));

  ASSERT_TRUE(send_buffer_.WriteStreamData(1024, 512, &writer));
  // Last offset is now 2048 as that's the end of the next slice.
  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
  send_buffer_.OnStreamDataConsumed(1024);

  // If data in 1st slice gets ACK'ed, it shouldn't change the indexed slice
  QuicByteCount newly_acked_length;
  EXPECT_TRUE(send_buffer_.OnStreamDataAcked(0, 1024, &newly_acked_length));
  // Last offset is still 2048.
  EXPECT_EQ(2048u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));

  ASSERT_TRUE(
      send_buffer_.WriteStreamData(1024 + 512, 3840 - 1024 - 512, &writer));

  // Last offset is end offset of last slice.
  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
  QuicBuffer buffer(&allocator_, 60);
  memset(buffer.data(), 'e', buffer.size());
  QuicMemSlice slice(std::move(buffer));
  send_buffer_.SaveMemSlice(std::move(slice));

  EXPECT_EQ(3840u, QuicStreamSendBufferPeer::EndOffset(&send_buffer_));
}

TEST_F(QuicStreamSendBufferTest, SaveMemSliceSpan) {
  SimpleBufferAllocator allocator;
  QuicStreamSendBuffer send_buffer(&allocator);

  char data[1024];
  std::vector<std::pair<char*, size_t>> buffers;
  for (size_t i = 0; i < 10; ++i) {
    buffers.push_back(std::make_pair(data, 1024));
  }
  QuicTestMemSliceVector vector(buffers);

  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(vector.span()));
  EXPECT_EQ(10u, send_buffer.size());
}

TEST_F(QuicStreamSendBufferTest, SaveEmptyMemSliceSpan) {
  SimpleBufferAllocator allocator;
  QuicStreamSendBuffer send_buffer(&allocator);

  char data[1024];
  std::vector<std::pair<char*, size_t>> buffers;
  for (size_t i = 0; i < 10; ++i) {
    buffers.push_back(std::make_pair(data, 1024));
  }
  buffers.push_back(std::make_pair(nullptr, 0));
  QuicTestMemSliceVector vector(buffers);

  EXPECT_EQ(10 * 1024u, send_buffer.SaveMemSliceSpan(vector.span()));
  // Verify the empty slice does not get saved.
  EXPECT_EQ(10u, send_buffer.size());
}

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