/*
 * Copyright (C) 2009, 2010, 2012, 2013 Apple Inc. All rights reserved.
 * Copyright (C) 2012 Google Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_STRING_BUILDER_H_
#define THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_STRING_BUILDER_H_

#include "base/macros.h"
#include "third_party/blink/renderer/platform/wtf/text/atomic_string.h"
#include "third_party/blink/renderer/platform/wtf/text/integer_to_string_conversion.h"
#include "third_party/blink/renderer/platform/wtf/text/string_view.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/wtf_export.h"

namespace WTF {

class WTF_EXPORT StringBuilder {
  USING_FAST_MALLOC(StringBuilder);

 public:
  StringBuilder() : no_buffer_() {}
  ~StringBuilder() { Clear(); }

  void Append(const UChar*, unsigned length);
  void Append(const LChar*, unsigned length);

  ALWAYS_INLINE void Append(const char* characters, unsigned length) {
    Append(reinterpret_cast<const LChar*>(characters), length);
  }

  void Append(const StringBuilder& other) {
    if (!other.length_)
      return;

    if (!length_ && !HasBuffer() && !other.string_.IsNull()) {
      string_ = other.string_;
      length_ = other.string_.length();
      is_8bit_ = other.string_.Is8Bit();
      return;
    }

    if (other.Is8Bit())
      Append(other.Characters8(), other.length_);
    else
      Append(other.Characters16(), other.length_);
  }

  // NOTE: The semantics of this are different than StringView(..., offset,
  // length) in that an invalid offset or invalid length is a no-op instead of
  // an error.
  // TODO(esprehn): We should probably unify the semantics instead.
  void Append(const StringView& string, unsigned offset, unsigned length) {
    unsigned extent = offset + length;
    if (extent < offset || extent > string.length())
      return;

    // We can't do this before the above check since StringView's constructor
    // doesn't accept invalid offsets or lengths.
    Append(StringView(string, offset, length));
  }

  void Append(const StringView& string) {
    if (string.IsEmpty())
      return;

    // If we're appending to an empty builder, and there is not a buffer
    // (reserveCapacity has not been called), then share the impl if
    // possible.
    //
    // This is important to avoid string copies inside dom operations like
    // Node::textContent when there's only a single Text node child, or
    // inside the parser in the common case when flushing buffered text to
    // a Text node.
    StringImpl* impl = string.SharedImpl();
    if (!length_ && !HasBuffer() && impl) {
      string_ = impl;
      length_ = impl->length();
      is_8bit_ = impl->Is8Bit();
      return;
    }

    if (string.Is8Bit())
      Append(string.Characters8(), string.length());
    else
      Append(string.Characters16(), string.length());
  }

  void Append(UChar c) {
    if (is_8bit_ && c <= 0xFF) {
      Append(static_cast<LChar>(c));
      return;
    }
    EnsureBuffer16(1);
    buffer16_.push_back(c);
    ++length_;
  }

  void Append(LChar c) {
    if (!is_8bit_) {
      Append(static_cast<UChar>(c));
      return;
    }
    EnsureBuffer8(1);
    buffer8_.push_back(c);
    ++length_;
  }

  void Append(char c) { Append(static_cast<LChar>(c)); }

  void Append(UChar32 c) {
    if (U_IS_BMP(c)) {
      Append(static_cast<UChar>(c));
      return;
    }
    Append(U16_LEAD(c));
    Append(U16_TRAIL(c));
  }

  template <typename IntegerType>
  void AppendNumber(IntegerType number) {
    IntegerToStringConverter<IntegerType> converter(number);
    Append(converter.Characters8(), converter.length());
  }

  void AppendNumber(bool);

  void AppendNumber(float);

  void AppendNumber(double, unsigned precision = 6);

  // Like WTF::String::Format, supports Latin-1 only.
  PRINTF_FORMAT(2, 3)
  void AppendFormat(const char* format, ...);

  void erase(unsigned);

  String ToString();
  AtomicString ToAtomicString();
  String Substring(unsigned start, unsigned length) const;

  operator StringView() const {
    if (Is8Bit()) {
      return StringView(Characters8(), length());
    } else {
      return StringView(Characters16(), length());
    }
  }

  unsigned length() const { return length_; }
  bool IsEmpty() const { return !length_; }

  unsigned Capacity() const;
  void ReserveCapacity(unsigned new_capacity);

  // TODO(esprehn): Rename to shrink().
  void Resize(unsigned new_size);

  UChar operator[](unsigned i) const {
    SECURITY_DCHECK(i < length_);
    if (is_8bit_)
      return Characters8()[i];
    return Characters16()[i];
  }

  const LChar* Characters8() const {
    DCHECK(is_8bit_);
    if (!length())
      return nullptr;
    if (!string_.IsNull())
      return string_.Characters8();
    DCHECK(has_buffer_);
    return buffer8_.data();
  }

  const UChar* Characters16() const {
    DCHECK(!is_8bit_);
    if (!length())
      return nullptr;
    if (!string_.IsNull())
      return string_.Characters16();
    DCHECK(has_buffer_);
    return buffer16_.data();
  }

  bool Is8Bit() const { return is_8bit_; }
  void Ensure16Bit();

  void Clear();
  void Swap(StringBuilder&);

 private:
  static const unsigned kInlineBufferSize = 16;
  static unsigned InitialBufferSize() { return kInlineBufferSize; }

  typedef Vector<LChar, kInlineBufferSize / sizeof(LChar)> Buffer8;
  typedef Vector<UChar, kInlineBufferSize / sizeof(UChar)> Buffer16;

  void EnsureBuffer8(unsigned added_size) {
    DCHECK(is_8bit_);
    if (!HasBuffer())
      CreateBuffer8(added_size);
  }

  void EnsureBuffer16(unsigned added_size) {
    if (is_8bit_ || !HasBuffer())
      CreateBuffer16(added_size);
  }

  void CreateBuffer8(unsigned added_size);
  void CreateBuffer16(unsigned added_size);
  void ClearBuffer();
  bool HasBuffer() const { return has_buffer_; }

  String string_;
  union {
    char no_buffer_;
    Buffer8 buffer8_;
    Buffer16 buffer16_;
  };
  unsigned length_ = 0;
  bool is_8bit_ = true;
  bool has_buffer_ = false;

  DISALLOW_COPY_AND_ASSIGN(StringBuilder);
};

template <typename CharType>
bool Equal(const StringBuilder& s, const CharType* buffer, unsigned length) {
  if (s.length() != length)
    return false;

  if (s.Is8Bit())
    return Equal(s.Characters8(), buffer, length);

  return Equal(s.Characters16(), buffer, length);
}

template <typename CharType>
bool DeprecatedEqualIgnoringCase(const StringBuilder& s,
                                 const CharType* buffer,
                                 unsigned length) {
  if (s.length() != length)
    return false;

  if (s.Is8Bit())
    return DeprecatedEqualIgnoringCase(s.Characters8(), buffer, length);

  return DeprecatedEqualIgnoringCase(s.Characters16(), buffer, length);
}

// Unicode aware case insensitive string matching. Non-ASCII characters might
// match to ASCII characters. This function is rarely used to implement web
// platform features.
// This function is deprecated. We should introduce EqualIgnoringASCIICase() or
// EqualIgnoringUnicodeCase(). See crbug.com/627682
inline bool DeprecatedEqualIgnoringCase(const StringBuilder& s,
                                        const char* string) {
  return DeprecatedEqualIgnoringCase(s, reinterpret_cast<const LChar*>(string),
                                     SafeCast<wtf_size_t>(strlen(string)));
}

template <typename StringType>
bool Equal(const StringBuilder& a, const StringType& b) {
  if (a.length() != b.length())
    return false;

  if (!a.length())
    return true;

  if (a.Is8Bit()) {
    if (b.Is8Bit())
      return Equal(a.Characters8(), b.Characters8(), a.length());
    return Equal(a.Characters8(), b.Characters16(), a.length());
  }

  if (b.Is8Bit())
    return Equal(a.Characters16(), b.Characters8(), a.length());
  return Equal(a.Characters16(), b.Characters16(), a.length());
}

inline bool operator==(const StringBuilder& a, const StringBuilder& b) {
  return Equal(a, b);
}
inline bool operator!=(const StringBuilder& a, const StringBuilder& b) {
  return !Equal(a, b);
}
inline bool operator==(const StringBuilder& a, const String& b) {
  return Equal(a, b);
}
inline bool operator!=(const StringBuilder& a, const String& b) {
  return !Equal(a, b);
}
inline bool operator==(const String& a, const StringBuilder& b) {
  return Equal(b, a);
}
inline bool operator!=(const String& a, const StringBuilder& b) {
  return !Equal(b, a);
}

}  // namespace WTF

using WTF::StringBuilder;

#endif  // THIRD_PARTY_BLINK_RENDERER_PLATFORM_WTF_TEXT_STRING_BUILDER_H_
