// Copyright 2018 The Fuchsia 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 "src/developer/debug/shared/stream_buffer.h"

#include <string.h>

#include <algorithm>

namespace debug_ipc {

StreamBuffer::StreamBuffer() = default;
StreamBuffer::~StreamBuffer() = default;

void StreamBuffer::AddReadData(std::vector<char> data) {
  read_buffer_.push_back(std::move(data));
}

void StreamBuffer::SetWritable() {
  can_write_ = true;
  FlushWriteBuffer();
}

bool StreamBuffer::IsAvailable(size_t count) const {
  if (count == 0)
    return true;

  size_t current_node_offset = first_read_buffer_offset_;
  for (const auto& cur : read_buffer_) {
    size_t in_current = cur.size() - current_node_offset;
    if (count <= in_current)
      return true;
    count -= in_current;
    current_node_offset = 0;
  }
  return false;
}

size_t StreamBuffer::Read(char* buffer, size_t buffer_len) {
  return ReadOrPeek(buffer, buffer_len, true);
}

size_t StreamBuffer::Peek(char* buffer, size_t buffer_len) const {
  return const_cast<StreamBuffer*>(this)->ReadOrPeek(buffer, buffer_len, false);
}

void StreamBuffer::Write(std::vector<char> data) {
  write_buffer_.push_back(std::move(data));
  if (can_write_)
    FlushWriteBuffer();
}

size_t StreamBuffer::ReadOrPeek(char* buffer, size_t buffer_len,
                                bool erase_consumed) {
  size_t buffer_pos = 0;

  auto cur = read_buffer_.begin();
  size_t current_node_offset = first_read_buffer_offset_;
  while (cur != read_buffer_.end() && buffer_pos < buffer_len) {
    size_t in_current_block = cur->size() - current_node_offset;
    size_t to_copy = std::min(buffer_len - buffer_pos, in_current_block);

    memcpy(&buffer[buffer_pos], &(*cur)[current_node_offset], to_copy);
    buffer_pos += to_copy;
    current_node_offset += to_copy;

    if (to_copy == in_current_block) {
      // Consumed the last of this block, move to the next one.
      cur++;
      current_node_offset = 0;
    }
  }
  if (erase_consumed) {
    // Update the state to reflect these read bytes.
    while (read_buffer_.begin() != cur)
      read_buffer_.pop_front();
    first_read_buffer_offset_ = current_node_offset;
  }
  return buffer_pos;
}

void StreamBuffer::FlushWriteBuffer() {
  while (!write_buffer_.empty()) {
    const std::vector<char>& cur = write_buffer_.front();
    int32_t written = writer_->ConsumeStreamBufferData(
        &cur[first_write_buffer_offset_],
        cur.size() - first_write_buffer_offset_);
    first_write_buffer_offset_ += written;

    if (first_write_buffer_offset_ < cur.size()) {
      // Partial write, block until notified about more.
      can_write_ = false;
      return;
    }

    // Consumed all the data, advance to the next buffer.
    write_buffer_.pop_front();
    first_write_buffer_offset_ = 0;
  }
}

}  // namespace debug_ipc
