// 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/server/http_connection.h"

#include <string>

#include "base/memory/ref_counted.h"
#include "base/strings/string_piece.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {
namespace {

std::string GetTestString(int size) {
  std::string test_string;
  for (int i = 0; i < size; ++i) {
    test_string.push_back('A' + (i % 26));
  }
  return test_string;
}

TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity) {
  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
      new HttpConnection::ReadIOBuffer);
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->GetCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->RemainingCapacity());
  EXPECT_EQ(0, buffer->GetSize());

  const int kNewCapacity = HttpConnection::ReadIOBuffer::kInitialBufSize + 128;
  buffer->SetCapacity(kNewCapacity);
  EXPECT_EQ(kNewCapacity, buffer->GetCapacity());
  EXPECT_EQ(kNewCapacity, buffer->RemainingCapacity());
  EXPECT_EQ(0, buffer->GetSize());
}

TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity_WithData) {
  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
      new HttpConnection::ReadIOBuffer);
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->GetCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->RemainingCapacity());

  // Write arbitrary data up to kInitialBufSize.
  const std::string kReadData(
      GetTestString(HttpConnection::ReadIOBuffer::kInitialBufSize));
  memcpy(buffer->data(), kReadData.data(), kReadData.size());
  buffer->DidRead(kReadData.size());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->GetCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize -
                static_cast<int>(kReadData.size()),
            buffer->RemainingCapacity());
  EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
  EXPECT_EQ(kReadData,
            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));

  // Check if read data in the buffer is same after SetCapacity().
  const int kNewCapacity = HttpConnection::ReadIOBuffer::kInitialBufSize + 128;
  buffer->SetCapacity(kNewCapacity);
  EXPECT_EQ(kNewCapacity, buffer->GetCapacity());
  EXPECT_EQ(kNewCapacity - static_cast<int>(kReadData.size()),
            buffer->RemainingCapacity());
  EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
  EXPECT_EQ(kReadData,
            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));
}

TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity) {
  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
      new HttpConnection::ReadIOBuffer);
  EXPECT_TRUE(buffer->IncreaseCapacity());
  const int kExpectedInitialBufSize =
      HttpConnection::ReadIOBuffer::kInitialBufSize *
      HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor;
  EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
  EXPECT_EQ(kExpectedInitialBufSize, buffer->RemainingCapacity());
  EXPECT_EQ(0, buffer->GetSize());

  // Increase capacity until it fails.
  while (buffer->IncreaseCapacity());
  EXPECT_FALSE(buffer->IncreaseCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
            buffer->max_buffer_size());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
            buffer->GetCapacity());

  // Enlarge capacity limit.
  buffer->set_max_buffer_size(buffer->max_buffer_size() * 2);
  EXPECT_TRUE(buffer->IncreaseCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize *
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->GetCapacity());

  // Shrink capacity limit. It doesn't change capacity itself.
  buffer->set_max_buffer_size(
      HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize / 2);
  EXPECT_FALSE(buffer->IncreaseCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize *
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->GetCapacity());
}

TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity_WithData) {
  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
      new HttpConnection::ReadIOBuffer);
  EXPECT_TRUE(buffer->IncreaseCapacity());
  const int kExpectedInitialBufSize =
      HttpConnection::ReadIOBuffer::kInitialBufSize *
      HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor;
  EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
  EXPECT_EQ(kExpectedInitialBufSize, buffer->RemainingCapacity());
  EXPECT_EQ(0, buffer->GetSize());

  // Write arbitrary data up to kExpectedInitialBufSize.
  std::string kReadData(GetTestString(kExpectedInitialBufSize));
  memcpy(buffer->data(), kReadData.data(), kReadData.size());
  buffer->DidRead(kReadData.size());
  EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
  EXPECT_EQ(kExpectedInitialBufSize - static_cast<int>(kReadData.size()),
            buffer->RemainingCapacity());
  EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
  EXPECT_EQ(kReadData,
            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));

  // Increase capacity until it fails and check if read data in the buffer is
  // same.
  while (buffer->IncreaseCapacity());
  EXPECT_FALSE(buffer->IncreaseCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
            buffer->max_buffer_size());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
            buffer->GetCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize -
                static_cast<int>(kReadData.size()),
            buffer->RemainingCapacity());
  EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
  EXPECT_EQ(kReadData,
            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));
}

TEST(HttpConnectionTest, ReadIOBuffer_DidRead_DidConsume) {
  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
      new HttpConnection::ReadIOBuffer);
  const char* start_of_buffer = buffer->StartOfBuffer();
  EXPECT_EQ(start_of_buffer, buffer->data());

  // Read data.
  const int kReadLength = 128;
  const std::string kReadData(GetTestString(kReadLength));
  memcpy(buffer->data(), kReadData.data(), kReadLength);
  buffer->DidRead(kReadLength);
  // No change in total capacity.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
            buffer->GetCapacity());
  // Change in unused capacity because of read data.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize - kReadLength,
            buffer->RemainingCapacity());
  EXPECT_EQ(kReadLength, buffer->GetSize());
  // No change in start pointers of read data.
  EXPECT_EQ(start_of_buffer, buffer->StartOfBuffer());
  // Change in start pointer of unused buffer.
  EXPECT_EQ(start_of_buffer + kReadLength, buffer->data());
  // Test read data.
  EXPECT_EQ(kReadData, std::string(buffer->StartOfBuffer(), buffer->GetSize()));

  // Consume data partially.
  const int kConsumedLength = 32;
  ASSERT_LT(kConsumedLength, kReadLength);
  buffer->DidConsume(kConsumedLength);
  // Capacity reduced because read data was too small comparing to capacity.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->GetCapacity());
  // Change in unused capacity because of read data.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor -
                kReadLength + kConsumedLength,
            buffer->RemainingCapacity());
  // Change in read size.
  EXPECT_EQ(kReadLength - kConsumedLength, buffer->GetSize());
  // Start data could be changed even when capacity is reduced.
  start_of_buffer = buffer->StartOfBuffer();
  // Change in start pointer of unused buffer.
  EXPECT_EQ(start_of_buffer + kReadLength - kConsumedLength, buffer->data());
  // Change in read data.
  EXPECT_EQ(kReadData.substr(kConsumedLength),
            std::string(buffer->StartOfBuffer(), buffer->GetSize()));

  // Read more data.
  const int kReadLength2 = 64;
  buffer->DidRead(kReadLength2);
  // No change in total capacity.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->GetCapacity());
  // Change in unused capacity because of read data.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor -
                kReadLength + kConsumedLength - kReadLength2,
            buffer->RemainingCapacity());
  // Change in read size
  EXPECT_EQ(kReadLength - kConsumedLength + kReadLength2, buffer->GetSize());
  // No change in start pointer of read part.
  EXPECT_EQ(start_of_buffer, buffer->StartOfBuffer());
  // Change in start pointer of unused buffer.
  EXPECT_EQ(start_of_buffer + kReadLength - kConsumedLength + kReadLength2,
            buffer->data());

  // Consume data fully.
  buffer->DidConsume(kReadLength - kConsumedLength + kReadLength2);
  // Capacity reduced again because read data was too small.
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->GetCapacity());
  EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor /
                HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
            buffer->RemainingCapacity());
  // All reverts to initial because no data is left.
  EXPECT_EQ(0, buffer->GetSize());
  // Start data could be changed even when capacity is reduced.
  start_of_buffer = buffer->StartOfBuffer();
  EXPECT_EQ(start_of_buffer, buffer->data());
}

TEST(HttpConnectionTest, QueuedWriteIOBuffer_Append_DidConsume) {
  scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer(
      new HttpConnection::QueuedWriteIOBuffer());
  EXPECT_TRUE(buffer->IsEmpty());
  EXPECT_EQ(0, buffer->GetSizeToWrite());
  EXPECT_EQ(0, buffer->total_size());

  const std::string kData("data to write");
  EXPECT_TRUE(buffer->Append(kData));
  EXPECT_FALSE(buffer->IsEmpty());
  EXPECT_EQ(static_cast<int>(kData.size()), buffer->GetSizeToWrite());
  EXPECT_EQ(static_cast<int>(kData.size()), buffer->total_size());
  // First data to write is same to kData.
  EXPECT_EQ(kData, base::StringPiece(buffer->data(), buffer->GetSizeToWrite()));

  const std::string kData2("more data to write");
  EXPECT_TRUE(buffer->Append(kData2));
  EXPECT_FALSE(buffer->IsEmpty());
  // No change in size to write.
  EXPECT_EQ(static_cast<int>(kData.size()), buffer->GetSizeToWrite());
  // Change in total size.
  EXPECT_EQ(static_cast<int>(kData.size() + kData2.size()),
            buffer->total_size());
  // First data to write has not been changed. Same to kData.
  EXPECT_EQ(kData, base::StringPiece(buffer->data(), buffer->GetSizeToWrite()));

  // Consume data partially.
  const int kConsumedLength = kData.length() - 1;
  buffer->DidConsume(kConsumedLength);
  EXPECT_FALSE(buffer->IsEmpty());
  // Change in size to write.
  EXPECT_EQ(static_cast<int>(kData.size()) - kConsumedLength,
            buffer->GetSizeToWrite());
  // Change in total size.
  EXPECT_EQ(static_cast<int>(kData.size() + kData2.size()) - kConsumedLength,
            buffer->total_size());
  // First data to write has shrinked.
  EXPECT_EQ(kData.substr(kConsumedLength),
            base::StringPiece(buffer->data(), buffer->GetSizeToWrite()));

  // Consume first data fully.
  buffer->DidConsume(kData.size() - kConsumedLength);
  EXPECT_FALSE(buffer->IsEmpty());
  // Now, size to write is size of data added second.
  EXPECT_EQ(static_cast<int>(kData2.size()), buffer->GetSizeToWrite());
  // Change in total size.
  EXPECT_EQ(static_cast<int>(kData2.size()), buffer->total_size());
  // First data to write has changed to kData2.
  EXPECT_EQ(kData2,
            base::StringPiece(buffer->data(), buffer->GetSizeToWrite()));

  // Consume second data fully.
  buffer->DidConsume(kData2.size());
  EXPECT_TRUE(buffer->IsEmpty());
  EXPECT_EQ(0, buffer->GetSizeToWrite());
  EXPECT_EQ(0, buffer->total_size());
}

TEST(HttpConnectionTest, QueuedWriteIOBuffer_TotalSizeLimit) {
  scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer(
      new HttpConnection::QueuedWriteIOBuffer());
  EXPECT_EQ(HttpConnection::QueuedWriteIOBuffer::kDefaultMaxBufferSize + 0,
            buffer->max_buffer_size());

  // Set total size limit very small.
  buffer->set_max_buffer_size(10);

  const int kDataLength = 4;
  const std::string kData(kDataLength, 'd');
  EXPECT_TRUE(buffer->Append(kData));
  EXPECT_EQ(kDataLength, buffer->total_size());
  EXPECT_TRUE(buffer->Append(kData));
  EXPECT_EQ(kDataLength * 2, buffer->total_size());

  // Cannot append more data because it exceeds the limit.
  EXPECT_FALSE(buffer->Append(kData));
  EXPECT_EQ(kDataLength * 2, buffer->total_size());

  // Consume data partially.
  const int kConsumedLength = 2;
  buffer->DidConsume(kConsumedLength);
  EXPECT_EQ(kDataLength * 2 - kConsumedLength, buffer->total_size());

  // Can add more data.
  EXPECT_TRUE(buffer->Append(kData));
  EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());

  // Cannot append more data because it exceeds the limit.
  EXPECT_FALSE(buffer->Append(kData));
  EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());

  // Enlarge limit.
  buffer->set_max_buffer_size(20);
  // Can add more data.
  EXPECT_TRUE(buffer->Append(kData));
  EXPECT_EQ(kDataLength * 4 - kConsumedLength, buffer->total_size());
}

}  // namespace
}  // namespace net
