// Copyright (c) 2010 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 "pdf/chunk_stream.h"

#include <stddef.h>
#include <string.h>

#include <algorithm>
#include <limits>

namespace chrome_pdf {

ChunkStream::ChunkStream() : stream_size_(0) {}

ChunkStream::~ChunkStream() {}

void ChunkStream::Clear() {
  chunks_.clear();
  data_.clear();
  stream_size_ = 0;
}

void ChunkStream::Preallocate(size_t stream_size) {
  data_.reserve(stream_size);
  stream_size_ = stream_size;
}

size_t ChunkStream::GetSize() const {
  return data_.size();
}

bool ChunkStream::WriteData(size_t offset, void* buffer, size_t size) {
  if (std::numeric_limits<size_t>::max() - size < offset)
    return false;

  if (data_.size() < offset + size)
    data_.resize(offset + size);

  memcpy(&data_[offset], buffer, size);

  if (chunks_.empty()) {
    chunks_[offset] = size;
    return true;
  }

  auto start = GetStartChunk(offset);
  auto end = chunks_.upper_bound(offset + size);
  if (start == end) {  // No chunks to merge.
    chunks_[offset] = size;
    return true;
  }

  auto prev = end;
  --prev;
  size_t prev_size = prev->first + prev->second;

  size_t new_offset = std::min<size_t>(start->first, offset);
  size_t new_size = std::max<size_t>(prev_size, offset + size) - new_offset;

  chunks_.erase(start, end);
  chunks_[new_offset] = new_size;
  return true;
}

bool ChunkStream::ReadData(size_t offset, size_t size, void* buffer) const {
  if (!IsRangeAvailable(offset, size))
    return false;

  memcpy(buffer, &data_[offset], size);
  return true;
}

bool ChunkStream::GetMissedRanges(
    size_t offset,
    size_t size,
    std::vector<std::pair<size_t, size_t>>* ranges) const {
  if (IsRangeAvailable(offset, size))
    return false;

  ranges->clear();
  if (chunks_.empty()) {
    ranges->push_back(std::pair<size_t, size_t>(offset, size));
    return true;
  }

  auto start = GetStartChunk(offset);
  auto end = chunks_.upper_bound(offset + size);
  if (start == end) {  // No data in the current range available.
    ranges->push_back(std::pair<size_t, size_t>(offset, size));
    return true;
  }

  size_t cur_offset = offset;
  for (auto it = start; it != end; ++it) {
    if (cur_offset < it->first) {
      size_t new_size = it->first - cur_offset;
      ranges->push_back(std::pair<size_t, size_t>(cur_offset, new_size));
      cur_offset = it->first + it->second;
    } else if (cur_offset < it->first + it->second) {
      cur_offset = it->first + it->second;
    }
  }

  // Add last chunk.
  if (cur_offset < offset + size) {
    ranges->push_back(
        std::pair<size_t, size_t>(cur_offset, offset + size - cur_offset));
  }

  return true;
}

bool ChunkStream::IsRangeAvailable(size_t offset, size_t size) const {
  if (chunks_.empty())
    return false;

  if (std::numeric_limits<size_t>::max() - size < offset)
    return false;

  auto it = chunks_.upper_bound(offset);
  if (it == chunks_.begin())
    return false;  // No chunks includes offset byte.

  --it;  // Now it starts equal or before offset.
  return it->first + it->second >= offset + size;
}

size_t ChunkStream::GetFirstMissingByte() const {
  if (chunks_.empty())
    return 0;
  auto begin = chunks_.begin();
  return begin->first > 0 ? 0 : begin->second;
}

size_t ChunkStream::GetFirstMissingByteInInterval(size_t offset) const {
  if (chunks_.empty())
    return 0;
  auto it = chunks_.upper_bound(offset);
  if (it == chunks_.begin())
    return 0;
  --it;
  return it->first + it->second;
}

size_t ChunkStream::GetLastMissingByteInInterval(size_t offset) const {
  if (chunks_.empty())
    return stream_size_ - 1;
  auto it = chunks_.upper_bound(offset);
  if (it == chunks_.end())
    return stream_size_ - 1;
  return it->first - 1;
}

std::map<size_t, size_t>::const_iterator ChunkStream::GetStartChunk(
    size_t offset) const {
  auto start = chunks_.upper_bound(offset);
  if (start != chunks_.begin())
    --start;  // start now points to the key equal or lower than offset.
  if (start->first + start->second < offset)
    ++start;  // start element is entirely before current chunk, skip it.
  return start;
}

}  // namespace chrome_pdf
