/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "rtc_base/copy_on_write_buffer.h"

#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <utility>

#include "absl/algorithm/container.h"
#include "absl/strings/string_view.h"
#include "api/array_view.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "rtc_base/checks.h"
#include "rtc_base/ref_counted_object.h"

namespace webrtc {

CopyOnWriteBuffer::RawBuffer::RawBuffer(size_t size)
    : size_(size), data_(std::make_unique_for_overwrite<uint8_t[]>(size)) {}

scoped_refptr<CopyOnWriteBuffer::RefCountedBuffer>
CopyOnWriteBuffer::CreateBuffer(size_t capacity) {
  if (capacity == 0) {
    return nullptr;
  }
  return make_ref_counted<RefCountedBuffer>(capacity);
}

CopyOnWriteBuffer::CopyOnWriteBuffer() : offset_(0), size_(0) {
  RTC_DCHECK(IsConsistent());
}

CopyOnWriteBuffer::CopyOnWriteBuffer(const CopyOnWriteBuffer& buf)
    : buffer_(buf.buffer_), offset_(buf.offset_), size_(buf.size_) {}

CopyOnWriteBuffer::CopyOnWriteBuffer(CopyOnWriteBuffer&& buf) noexcept
    : buffer_(std::move(buf.buffer_)), offset_(buf.offset_), size_(buf.size_) {
  buf.offset_ = 0;
  buf.size_ = 0;
  RTC_DCHECK(IsConsistent());
}

CopyOnWriteBuffer::CopyOnWriteBuffer(absl::string_view s)
    : CopyOnWriteBuffer(s.data(), s.length()) {}

CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size)
    : buffer_(CreateBuffer(/*capacity=*/size)), offset_(0), size_(size) {
  // note - the RefCountedBuffer will be created uninitialized.
  RTC_DCHECK(IsConsistent());
}

CopyOnWriteBuffer::CopyOnWriteBuffer(size_t size, size_t capacity)
    : buffer_(CreateBuffer(std::max(size, capacity))), offset_(0), size_(size) {
  RTC_DCHECK(IsConsistent());
}

CopyOnWriteBuffer::~CopyOnWriteBuffer() = default;

bool CopyOnWriteBuffer::operator==(const CopyOnWriteBuffer& buf) const {
  // Must either be the same view of the same buffer or have the same contents.
  RTC_DCHECK(IsConsistent());
  RTC_DCHECK(buf.IsConsistent());
  return size_ == buf.size_ &&
         (cdata() == buf.cdata() || memcmp(cdata(), buf.cdata(), size_) == 0);
}

void CopyOnWriteBuffer::SetSize(size_t size) {
  RTC_DCHECK(IsConsistent());
  if (size <= size_) {
    size_ = size;
    return;
  }

  UnshareAndEnsureCapacity(std::max(capacity(), size));
  size_ = size;
  RTC_DCHECK(IsConsistent());
}

void CopyOnWriteBuffer::EnsureCapacity(size_t new_capacity) {
  RTC_DCHECK(IsConsistent());
  if (new_capacity <= capacity()) {
    return;
  }

  UnshareAndEnsureCapacity(new_capacity);
  RTC_DCHECK(IsConsistent());
}

void CopyOnWriteBuffer::Clear() {
  if (!buffer_)
    return;

  if (!buffer_->HasOneRef()) {
    buffer_ = CreateBuffer(capacity());
  }
  offset_ = 0;
  size_ = 0;
  RTC_DCHECK(IsConsistent());
}

void CopyOnWriteBuffer::Set(ArrayView<const uint8_t> data) {
  RTC_DCHECK(IsConsistent());
  if (data.empty()) {
    offset_ = 0;
    size_ = 0;
    return;
  }

  if (buffer_ == nullptr || !buffer_->HasOneRef() ||
      buffer_->capacity() < data.size()) {
    buffer_ = CreateBuffer(std::max(data.size(), capacity()));
  }
  absl::c_copy(data, buffer_->data().begin());
  offset_ = 0;
  size_ = data.size();

  RTC_DCHECK(IsConsistent());
}

void CopyOnWriteBuffer::Append(ArrayView<const uint8_t> data) {
  RTC_DCHECK(IsConsistent());
  if (data.empty()) {
    return;
  }

  UnshareAndEnsureCapacity(std::max(capacity(), size_ + data.size()));
  absl::c_copy(data, buffer_->data().subspan(offset_ + size_).begin());
  size_ += data.size();

  RTC_DCHECK(IsConsistent());
}

void CopyOnWriteBuffer::UnshareAndEnsureCapacity(size_t new_capacity) {
  if (buffer_ != nullptr && buffer_->HasOneRef() &&
      new_capacity <= capacity()) {
    return;
  }

  scoped_refptr<RefCountedBuffer> b = CreateBuffer(new_capacity);
  absl::c_copy(AsConstSpan(), b->data().begin());
  offset_ = 0;
  buffer_ = std::move(b);
  RTC_DCHECK(IsConsistent());
}

}  // namespace webrtc
