// Copyright 2017 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 <string.h>
#include <zircon/assert.h>

#include <atomic>
#include <new>

#include <fbl/algorithm.h>
#include <fbl/string.h>

namespace fbl {
namespace {

size_t SumLengths(const String* begin, const String* end, const String** last_non_empty_string) {
  size_t total_length = 0U;
  for (const String* it = begin; it != end; it++) {
    if (!it->empty()) {
      *last_non_empty_string = it;
      total_length += it->length();
    }
  }
  return total_length;
}

void Concat(char* data, const String* begin, const String* end) {
  for (const String* it = begin; it != end; it++) {
    memcpy(data, it->data(), it->length());
    data += it->length();
  }
  *data = 0;
}

}  // namespace

String::EmptyBuffer String::gEmpty;

void String::clear() {
  ReleaseRef(data_);
  InitWithEmpty();
}

int String::compare(const String& other) const {
  size_t len = std::min(length(), other.length());
  int retval = memcmp(data(), other.data(), len);
  if (retval == 0) {
    if (length() == other.length()) {
      return 0;
    }
    return length() < other.length() ? -1 : 1;
  }
  return retval;
}

void String::swap(String& other) {
  char* temp_data = data_;
  data_ = other.data_;
  other.data_ = temp_data;
}

String& String::operator=(const String& other) {
  AcquireRef(other.data_);
  ReleaseRef(data_);  // release after acquire in case other == *this
  data_ = other.data_;
  return *this;
}

String& String::operator=(String&& other) noexcept {
  ReleaseRef(data_);
  data_ = other.data_;
  other.InitWithEmpty();
  return *this;
}

void String::Set(const char* data, size_t length) {
  char* temp_data = data_;
  Init(data, length);
  ReleaseRef(temp_data);  // release after init in case data is within data_
}

String String::Concat(std::initializer_list<String> strings) {
  const String* last_non_empty_string = nullptr;
  size_t total_length = SumLengths(strings.begin(), strings.end(), &last_non_empty_string);
  if (last_non_empty_string == nullptr) {
    return String();
  }
  if (total_length == last_non_empty_string->length()) {
    return *last_non_empty_string;
  }

  char* data = AllocData(total_length);

  fbl::Concat(data, strings.begin(), last_non_empty_string + 1);
  return String(data, nullptr);
}

void String::Init(const char* data, size_t length) {
  if (length == 0U) {
    InitWithEmpty();
    return;
  }

  data_ = AllocData(length);
  memcpy(data_, data, length);
  data_[length] = 0U;
}

void String::Init(size_t count, char ch) {
  if (count == 0U) {
    InitWithEmpty();
    return;
  }

  data_ = AllocData(count);
  memset(data_, ch, count);
  data_[count] = 0U;
}

void String::InitWithEmpty() {
  gEmpty.ref_count.fetch_add(1U, std::memory_order_relaxed);
  data_ = &gEmpty.nul;
}

char* String::AllocData(size_t length) {
  void* buffer = operator new(buffer_size(length));
  return InitData(buffer, length);
}

char* String::InitData(void* buffer, size_t length) {
  char* data = static_cast<char*>(buffer) + kDataFieldOffset;
  *length_field_of(data) = length;
  new (ref_count_field_of(data)) std::atomic_uint(1U);
  return data;
}

void String::AcquireRef(char* data) {
  ref_count_field_of(data)->fetch_add(1U, std::memory_order_relaxed);
}

void String::ReleaseRef(char* data) {
  unsigned int prior_count = ref_count_field_of(data)->fetch_sub(1U, std::memory_order_release);
  ZX_DEBUG_ASSERT(prior_count != 0U);
  if (prior_count == 1U) {
    atomic_thread_fence(std::memory_order_acquire);
    operator delete(data - kDataFieldOffset);
  }
}

bool operator==(const String& lhs, const String& rhs) {
  return lhs.length() == rhs.length() && memcmp(lhs.data(), rhs.data(), lhs.length()) == 0;
}

}  // namespace fbl
