#include "quiche/http2/adapter/chunked_buffer.h"

#include <algorithm>
#include <memory>
#include <utility>
#include <vector>

namespace http2 {
namespace adapter {

namespace {

constexpr size_t kKilobyte = 1024;
size_t RoundUpToNearestKilobyte(size_t n) {
  // The way to think of this bit math is: it fills in all of the least
  // significant bits less than 1024, then adds one. This guarantees that all of
  // those bits end up as 0, hence rounding up to a multiple of 1024.
  return ((n - 1) | (kKilobyte - 1)) + 1;
}

}  // namespace

void ChunkedBuffer::Append(absl::string_view data) {
  total_size_ += data.size();
  // Appends the data by copying it.
  const size_t to_copy = std::min(TailBytesFree(), data.size());
  if (to_copy > 0) {
    chunks_.back().AppendSuffix(data.substr(0, to_copy));
    data.remove_prefix(to_copy);
  }
  EnsureTailBytesFree(data.size());
  chunks_.back().AppendSuffix(data);
}

void ChunkedBuffer::Append(std::unique_ptr<char[]> data, size_t size) {
  total_size_ += size;
  if (TailBytesFree() >= size) {
    // Copies the data into the existing last chunk, since it will fit.
    Chunk& c = chunks_.back();
    c.AppendSuffix(absl::string_view(data.get(), size));
    return;
  }
  while (!chunks_.empty() && chunks_.front().Empty()) {
    chunks_.pop_front();
  }
  // Appends the memory to the end of the deque, since it won't fit in an
  // existing chunk.
  absl::string_view v = {data.get(), size};
  chunks_.push_back({std::move(data), size, v});
}

ChunkedBuffer::AppendRegion::~AppendRegion() {
  Chunk& c = parent->chunks_.back();
  c.live = absl::string_view(c.live.data(), c.live.size() + written);
  parent->total_size_ += written;
}

ChunkedBuffer::AppendRegion ChunkedBuffer::GetAppendRegion() {
  if (TailBytesFree() == 0) {
    EnsureTailBytesFree(kDefaultChunkSize);
  }
  Chunk& c = chunks_.back();
  return AppendRegion(c.data.get() + c.LiveDataOffset() + c.live.size(),
                      c.TailBytesFree(), 0, this);
}

absl::string_view ChunkedBuffer::GetPrefix() const {
  if (chunks_.empty()) {
    return "";
  }
  return chunks_.front().live;
}

std::vector<absl::string_view> ChunkedBuffer::Read() const {
  std::vector<absl::string_view> result;
  result.reserve(chunks_.size());
  for (const Chunk& c : chunks_) {
    result.push_back(c.live);
  }
  return result;
}

void ChunkedBuffer::RemovePrefix(size_t n) {
  while (!Empty() && n > 0) {
    Chunk& c = chunks_.front();
    const size_t to_remove = std::min(n, c.live.size());
    c.RemovePrefix(to_remove);
    n -= to_remove;
    total_size_ -= to_remove;
    if (c.Empty()) {
      TrimFirstChunk();
    }
  }
}

bool ChunkedBuffer::Empty() const {
  return chunks_.empty() ||
         (chunks_.size() == 1 && chunks_.front().live.empty());
}

void ChunkedBuffer::Chunk::RemovePrefix(size_t n) {
  QUICHE_DCHECK_GE(live.size(), n);
  live.remove_prefix(n);
}

void ChunkedBuffer::Chunk::AppendSuffix(absl::string_view to_append) {
  QUICHE_DCHECK_GE(TailBytesFree(), to_append.size());
  if (live.empty()) {
    std::copy(to_append.begin(), to_append.end(), data.get());
    // Live needs to be initialized, since it points to nullptr.
    live = absl::string_view(data.get(), to_append.size());
  } else {
    std::copy(to_append.begin(), to_append.end(),
              const_cast<char*>(live.data()) + live.size());
    // Live can be extended, since it already points to valid data.
    live = absl::string_view(live.data(), live.size() + to_append.size());
  }
}

size_t ChunkedBuffer::TailBytesFree() const {
  if (chunks_.empty()) {
    return 0;
  }
  return chunks_.back().TailBytesFree();
}

void ChunkedBuffer::EnsureTailBytesFree(size_t n) {
  if (TailBytesFree() >= n) {
    return;
  }
  const size_t to_allocate = RoundUpToNearestKilobyte(n);
  auto data = std::unique_ptr<char[]>(new char[to_allocate]);
  absl::string_view live(data.get(), 0);
  chunks_.push_back({std::move(data), to_allocate, live});
}

void ChunkedBuffer::TrimFirstChunk() {
  // Leave the first chunk, if it's the only one and already the default size.
  if (chunks_.empty() ||
      (chunks_.size() == 1 && chunks_.front().size == kDefaultChunkSize)) {
    return;
  }
  chunks_.pop_front();
}

}  // namespace adapter
}  // namespace http2
