// Copyright 2017 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "nb/multipart_allocator.h"

#include "starboard/log.h"
#include "starboard/memory.h"

namespace nb {

MultipartAllocator::Allocations::Allocations(void* buffer, int buffer_size)
    : number_of_buffers_(1),
      buffers_(&buffer_),
      buffer_sizes_(&buffer_size_),
      buffer_(buffer),
      buffer_size_(buffer_size) {
  SB_DCHECK(buffer != NULL);
  SB_DCHECK(buffer_size > 0);
}

MultipartAllocator::Allocations::Allocations(int number_of_buffers,
                                             void** buffers,
                                             const int* buffer_sizes)
    : number_of_buffers_(0), buffers_(NULL), buffer_sizes_(NULL) {
  SB_DCHECK(number_of_buffers > 0);
  SB_DCHECK(buffers != NULL);
  SB_DCHECK(buffer_sizes != NULL);

  Assign(number_of_buffers, buffers, buffer_sizes);

  for (int i = 0; i < number_of_buffers_; ++i) {
    SB_DCHECK(buffers_[i] != NULL);
    SB_DCHECK(buffer_sizes_[i] > 0);
  }
}

MultipartAllocator::Allocations::Allocations(const Allocations& that)
    : number_of_buffers_(0), buffers_(NULL), buffer_sizes_(NULL) {
  Assign(that.number_of_buffers_, that.buffers_, that.buffer_sizes_);
}

MultipartAllocator::Allocations::~Allocations() {
  Destroy();
}

MultipartAllocator::Allocations& MultipartAllocator::Allocations::operator=(
    const Allocations& that) {
  Destroy();
  Assign(that.number_of_buffers_, that.buffers_, that.buffer_sizes_);
  return *this;
}

int MultipartAllocator::Allocations::size() const {
  int size = 0;

  for (size_t i = 0; i < number_of_buffers_; ++i) {
    size += buffer_sizes_[i];
  }

  return size;
}

void MultipartAllocator::Allocations::ShrinkTo(int size) {
  for (size_t i = 0; i < number_of_buffers_; ++i) {
    if (size >= buffer_sizes_[i]) {
      size -= buffer_sizes_[i];
    } else {
      buffer_sizes_[i] = size;
      size = 0;
      ++i;
      while (i < number_of_buffers_) {
        buffer_sizes_[i] = 0;
        ++i;
      }
      break;
    }
  }

  SB_DCHECK(size == 0);
}

void MultipartAllocator::Allocations::Write(int destination_offset,
                                            const void* src,
                                            int size) {
  size_t buffer_index = 0;
  const uint8_t* src_in_uint8 = static_cast<const uint8_t*>(src);
  while (size > 0) {
    if (buffer_index >= number_of_buffers_) {
      SB_NOTREACHED();
      return;
    }
    if (buffer_sizes_[buffer_index] <= destination_offset) {
      destination_offset -= buffer_sizes_[buffer_index];
    } else {
      int bytes_to_copy =
          std::min(size, buffer_sizes_[buffer_index] - destination_offset);
      uint8_t* destination_in_uint8 =
          static_cast<uint8_t*>(buffers_[buffer_index]);
      SbMemoryCopy(destination_in_uint8 + destination_offset, src_in_uint8,
                   bytes_to_copy);
      destination_offset = 0;
      src_in_uint8 += bytes_to_copy;
      size -= bytes_to_copy;
    }
    ++buffer_index;
  }
}

void MultipartAllocator::Allocations::Read(void* destination) const {
  uint8_t* destination_in_uint8 = static_cast<uint8_t*>(destination);

  for (size_t i = 0; i < number_of_buffers_; ++i) {
    SbMemoryCopy(destination_in_uint8, buffers_[i], buffer_sizes_[i]);
    destination_in_uint8 += buffer_sizes_[i];
  }
}

void MultipartAllocator::Allocations::Assign(int number_of_buffers,
                                             void** buffers,
                                             const int* buffer_sizes) {
  SB_DCHECK(number_of_buffers_ == 0);
  SB_DCHECK(buffers_ == NULL);
  SB_DCHECK(buffer_sizes_ == NULL);

  number_of_buffers_ = number_of_buffers;
  if (number_of_buffers_ == 0) {
    buffers_ = NULL;
    buffer_sizes_ = NULL;
    return;
  }
  if (number_of_buffers_ == 1) {
    buffers_ = &buffer_;
    buffer_sizes_ = &buffer_size_;
    buffer_ = buffers[0];
    buffer_size_ = buffer_sizes[0];
    return;
  }
  buffers_ = new void*[number_of_buffers_];
  buffer_sizes_ = new int[number_of_buffers_];
  SbMemoryCopy(buffers_, buffers, sizeof(*buffers_) * number_of_buffers_);
  SbMemoryCopy(buffer_sizes_, buffer_sizes,
               sizeof(*buffer_sizes_) * number_of_buffers_);
}

void MultipartAllocator::Allocations::Destroy() {
  if (number_of_buffers_ > 1) {
    delete[] buffers_;
    delete[] buffer_sizes_;
  }
  number_of_buffers_ = 0;
  buffers_ = NULL;
  buffer_sizes_ = NULL;
}

}  // namespace nb
