// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of dart._internal;

/// Builds a list of bytes, allowing bytes and lists of bytes to be added at the
/// end.
///
/// Used to efficiently collect bytes and lists of bytes.
abstract interface class BytesBuilder {
  /// Construct a new empty [BytesBuilder].
  ///
  /// If [copy] is true (the default), the created builder is a *copying*
  /// builder. A copying builder maintains its own internal buffer and copies
  /// the bytes added to it eagerly.
  ///
  /// If [copy] set to false, the created builder assumes that lists added
  /// to it will not change.
  /// Any [Uint8List] added using [add] is kept until
  /// [toBytes] or [takeBytes] is called,
  /// and only then are their contents copied.
  /// A non-[Uint8List] may be copied eagerly.
  /// If only a single [Uint8List] is added to the builder,
  /// that list is returned by [toBytes] or [takeBytes] directly, without any copying.
  /// A list added to a non-copying builder *should not* change its content
  /// after being added, and it *must not* change its length after being added.
  /// (Normal [Uint8List]s are fixed length lists, but growing lists implementing
  /// [Uint8List] exist.)
  factory BytesBuilder({bool copy = true}) =>
      copy ? _CopyingBytesBuilder() : _BytesBuilder();

  /// Appends [bytes] to the current contents of this builder.
  ///
  /// Each value of [bytes] will be truncated
  /// to an 8-bit value in the range 0 .. 255.
  void add(List<int> bytes);

  /// Appends [byte] to the current contents of this builder.
  ///
  /// The [byte] will be truncated to an 8-bit value in the range 0 .. 255.
  void addByte(int byte);

  /// Returns the bytes currently contained in this builder and clears it.
  ///
  /// The returned list may be a view of a larger buffer.
  Uint8List takeBytes();

  /// Returns a copy of the current byte contents of this builder.
  ///
  /// Leaves the contents of this builder intact.
  Uint8List toBytes();

  /// The number of bytes in this builder.
  int get length;

  /// Whether the buffer is empty.
  bool get isEmpty;

  /// Whether the buffer is non-empty.
  bool get isNotEmpty;

  /// Clears the contents of this builder.
  ///
  /// The current contents are discarded and this builder becomes empty.
  void clear();
}

/// A [BytesBuilder] which appends bytes to a growing internal buffer.
class _CopyingBytesBuilder implements BytesBuilder {
  /// Initial size of internal buffer.
  static const int _initSize = 1024;

  /// Reusable empty [Uint8List].
  ///
  /// Safe for reuse because a fixed-length empty list is immutable.
  static final _emptyList = Uint8List(0);

  /// Current count of bytes written to buffer.
  int _length = 0;

  /// Internal buffer accumulating bytes.
  ///
  /// Will grow as necessary
  Uint8List _buffer;

  _CopyingBytesBuilder() : _buffer = _emptyList;

  void add(List<int> bytes) {
    int byteCount = bytes.length;
    if (byteCount == 0) return;
    int required = _length + byteCount;
    if (_buffer.length < required) {
      _grow(required);
    }
    assert(_buffer.length >= required);
    if (bytes is Uint8List) {
      _buffer.setRange(_length, required, bytes);
    } else {
      for (int i = 0; i < byteCount; i++) {
        _buffer[_length + i] = bytes[i];
      }
    }
    _length = required;
  }

  void addByte(int byte) {
    if (_buffer.length == _length) {
      // The grow algorithm always at least doubles.
      // If we added one to _length it would quadruple unnecessarily.
      _grow(_length);
    }
    assert(_buffer.length > _length);
    _buffer[_length] = byte;
    _length++;
  }

  void _grow(int required) {
    // We will create a list in the range of 2-4 times larger than
    // required.
    int newSize = required * 2;
    if (newSize < _initSize) {
      newSize = _initSize;
    } else {
      newSize = _pow2roundup(newSize);
    }
    var newBuffer = Uint8List(newSize);
    newBuffer.setRange(0, _buffer.length, _buffer);
    _buffer = newBuffer;
  }

  Uint8List takeBytes() {
    if (_length == 0) return _emptyList;
    var buffer = Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length);
    _clear();
    return buffer;
  }

  Uint8List toBytes() {
    if (_length == 0) return _emptyList;
    return Uint8List.fromList(
      Uint8List.view(_buffer.buffer, _buffer.offsetInBytes, _length),
    );
  }

  int get length => _length;

  bool get isEmpty => _length == 0;

  bool get isNotEmpty => _length != 0;

  void clear() {
    _clear();
  }

  void _clear() {
    _length = 0;
    _buffer = _emptyList;
  }

  /// Rounds numbers <= 2^32 up to the nearest power of 2.
  static int _pow2roundup(int x) {
    assert(x > 0);
    --x;
    x |= x >> 1;
    x |= x >> 2;
    x |= x >> 4;
    x |= x >> 8;
    x |= x >> 16;
    return x + 1;
  }
}

/// A non-copying [BytesBuilder].
///
/// Accumulates lists of integers and lazily builds
/// a collected list with all the bytes when requested.
class _BytesBuilder implements BytesBuilder {
  int _length = 0;
  final List<Uint8List> _chunks = [];

  void add(List<int> bytes) {
    Uint8List typedBytes;
    if (bytes is Uint8List) {
      typedBytes = bytes;
    } else {
      typedBytes = Uint8List.fromList(bytes);
    }
    _chunks.add(typedBytes);
    _length += typedBytes.length;
  }

  void addByte(int byte) {
    // TODO(lrn): Optimize repeated `addByte` calls.
    _chunks.add(Uint8List(1)..[0] = byte);
    _length++;
  }

  Uint8List takeBytes() {
    if (_length == 0) return _CopyingBytesBuilder._emptyList;
    if (_chunks.length == 1) {
      var buffer = _chunks[0];
      _clear();
      return buffer;
    }
    var buffer = Uint8List(_length);
    int offset = 0;
    for (var chunk in _chunks) {
      buffer.setRange(offset, offset + chunk.length, chunk);
      offset += chunk.length;
    }
    _clear();
    return buffer;
  }

  Uint8List toBytes() {
    if (_length == 0) return _CopyingBytesBuilder._emptyList;
    var buffer = Uint8List(_length);
    int offset = 0;
    for (var chunk in _chunks) {
      buffer.setRange(offset, offset + chunk.length, chunk);
      offset += chunk.length;
    }
    return buffer;
  }

  int get length => _length;

  bool get isEmpty => _length == 0;

  bool get isNotEmpty => _length != 0;

  void clear() {
    _clear();
  }

  void _clear() {
    _length = 0;
    _chunks.clear();
  }
}
