// Copyright (c) 2012 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 "content/browser/speech/chunked_byte_buffer.h"

#include <algorithm>
#include <utility>

#include "base/big_endian.h"
#include "base/lazy_instance.h"
#include "base/logging.h"

namespace {

static const size_t kHeaderLength = sizeof(uint32_t);

static_assert(sizeof(size_t) >= kHeaderLength,
              "chunked byte buffer not supported on this architecture");

}  // namespace

namespace content {

ChunkedByteBuffer::ChunkedByteBuffer()
    : partial_chunk_(new Chunk()),
      total_bytes_stored_(0) {
}

ChunkedByteBuffer::~ChunkedByteBuffer() {
  Clear();
}

void ChunkedByteBuffer::Append(const uint8_t* start, size_t length) {
  size_t remaining_bytes = length;
  const uint8_t* next_data = start;

  while (remaining_bytes > 0) {
    DCHECK(partial_chunk_ != nullptr);
    size_t insert_length = 0;
    bool header_completed = false;
    bool content_completed = false;
    std::vector<uint8_t>* insert_target;

    if (partial_chunk_->header.size() < kHeaderLength) {
      const size_t bytes_to_complete_header =
          kHeaderLength - partial_chunk_->header.size();
      insert_length = std::min(bytes_to_complete_header, remaining_bytes);
      insert_target = &partial_chunk_->header;
      header_completed = (remaining_bytes >= bytes_to_complete_header);
    } else {
      DCHECK_LT(partial_chunk_->content->size(),
                partial_chunk_->ExpectedContentLength());
      const size_t bytes_to_complete_chunk =
          partial_chunk_->ExpectedContentLength() -
          partial_chunk_->content->size();
      insert_length = std::min(bytes_to_complete_chunk, remaining_bytes);
      insert_target = partial_chunk_->content.get();
      content_completed = (remaining_bytes >= bytes_to_complete_chunk);
    }

    DCHECK_GT(insert_length, 0U);
    DCHECK_LE(insert_length, remaining_bytes);
    DCHECK_LE(next_data + insert_length, start + length);
    insert_target->insert(insert_target->end(),
                          next_data,
                          next_data + insert_length);
    next_data += insert_length;
    remaining_bytes -= insert_length;

    if (header_completed) {
      DCHECK_EQ(partial_chunk_->header.size(), kHeaderLength);
      if (partial_chunk_->ExpectedContentLength() == 0) {
        // Handle zero-byte chunks.
        chunks_.push_back(std::move(partial_chunk_));
        partial_chunk_.reset(new Chunk());
      } else {
        partial_chunk_->content->reserve(
            partial_chunk_->ExpectedContentLength());
      }
    } else if (content_completed) {
      DCHECK_EQ(partial_chunk_->content->size(),
                partial_chunk_->ExpectedContentLength());
      chunks_.push_back(std::move(partial_chunk_));
      partial_chunk_.reset(new Chunk());
    }
  }
  DCHECK_EQ(next_data, start + length);
  total_bytes_stored_ += length;
}

void ChunkedByteBuffer::Append(base::StringPiece string) {
  Append(reinterpret_cast<const uint8_t*>(string.data()), string.size());
}

bool ChunkedByteBuffer::HasChunks() const {
  return !chunks_.empty();
}

std::unique_ptr<std::vector<uint8_t>> ChunkedByteBuffer::PopChunk() {
  if (chunks_.empty())
    return std::unique_ptr<std::vector<uint8_t>>();
  std::unique_ptr<Chunk> chunk = std::move(*chunks_.begin());
  chunks_.erase(chunks_.begin());
  DCHECK_EQ(chunk->header.size(), kHeaderLength);
  DCHECK_EQ(chunk->content->size(), chunk->ExpectedContentLength());
  total_bytes_stored_ -= chunk->content->size();
  total_bytes_stored_ -= kHeaderLength;
  return std::move(chunk->content);
}

void ChunkedByteBuffer::Clear() {
  chunks_.clear();
  partial_chunk_.reset(new Chunk());
  total_bytes_stored_ = 0;
}

ChunkedByteBuffer::Chunk::Chunk() : content(new std::vector<uint8_t>()) {}

ChunkedByteBuffer::Chunk::~Chunk() {
}

size_t ChunkedByteBuffer::Chunk::ExpectedContentLength() const {
  DCHECK_EQ(header.size(), kHeaderLength);
  uint32_t content_length = 0;
  base::ReadBigEndian(reinterpret_cast<const char*>(&header[0]),
                      &content_length);
  return static_cast<size_t>(content_length);
}

}  // namespace content
