// Copyright (c) 2020, 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.

import 'dart:convert';
import 'dart:typed_data';

/// Puts a buffer in front of a [Sink<List<int>>].
class BufferedSink {
  static const int _SIZE = 128 * 1024;
  static const int _SAFE_LENGTH = _SIZE - 5;

  final BytesBuilder _builder = BytesBuilder(copy: false);

  Uint8List _buffer = Uint8List(_SIZE);
  int _length = 0;

  final Int64List _int64Buffer = Int64List(1);
  late final Uint8List _int64BufferUint8 = _int64Buffer.buffer.asUint8List();

  final Float64List _doubleBuffer = Float64List(1);
  late final Uint8List _doubleBufferUint8 = _doubleBuffer.buffer.asUint8List();

  BufferedSink();

  int get offset => _builder.length + _length;

  Uint8List takeBytes() {
    _builder.add(_buffer.sublist(0, _length));
    return _builder.takeBytes();
  }

  @pragma("vm:prefer-inline")
  void writeBool(bool value) {
    writeByte(value ? 1 : 0);
  }

  @pragma("vm:prefer-inline")
  void writeByte(int byte) {
    assert((byte & 0xFF) == byte);
    _addByte(byte);
  }

  void writeBytes(Uint8List bytes) {
    if (bytes.isEmpty) {
      return;
    }

    // Usually the bytes is short, and fits the current buffer.
    if (_length + bytes.length < _SIZE) {
      _buffer.setRange(_length, _length + bytes.length, bytes);
      _length += bytes.length;
      return;
    }

    // If the bytes is too long, add separate buffers.
    if (bytes.length >= _SIZE) {
      _builder.add(_buffer.sublist(0, _length));
      _builder.add(bytes);
      // Start a new buffer.
      _buffer = Uint8List(_SIZE);
      _length = 0;
      return;
    }

    // Copy as much as we can into the current buffer.
    _buffer.setRange(_length, _SIZE, bytes);
    _builder.add(_buffer);

    // Copy the remainder into a new buffer.
    var alreadyCopied = _SIZE - _length;
    var remainder = bytes.length - alreadyCopied;
    _buffer = Uint8List(_SIZE);
    _buffer.setRange(0, remainder, bytes, alreadyCopied);
    _length = remainder;
  }

  void writeDouble(double value) {
    _doubleBuffer[0] = value;
    _addByte4(
      _doubleBufferUint8[0],
      _doubleBufferUint8[1],
      _doubleBufferUint8[2],
      _doubleBufferUint8[3],
    );
    _addByte4(
      _doubleBufferUint8[4],
      _doubleBufferUint8[5],
      _doubleBufferUint8[6],
      _doubleBufferUint8[7],
    );
  }

  void writeEnum(Enum e) {
    writeByte(e.index);
  }

  void writeIf<T extends Object>(bool condition, void Function() ifTrue) {
    if (condition) {
      writeBool(true);
      ifTrue();
    } else {
      writeBool(false);
    }
  }

  void writeIfType<T extends Object>(
    Object? object,
    void Function(T t) ifTrue,
  ) {
    if (object is T) {
      writeBool(true);
      ifTrue(object);
    } else {
      writeBool(false);
    }
  }

  void writeInt64(int value) {
    _int64Buffer[0] = value;
    _addByte4(
      _int64BufferUint8[0],
      _int64BufferUint8[1],
      _int64BufferUint8[2],
      _int64BufferUint8[3],
    );
    _addByte4(
      _int64BufferUint8[4],
      _int64BufferUint8[5],
      _int64BufferUint8[6],
      _int64BufferUint8[7],
    );
  }

  /// Writes [items], converts to [List] first.
  void writeIterable<T>(Iterable<T> items, void Function(T x) writeItem) {
    writeList(items.toList(), writeItem);
  }

  void writeList<T>(List<T> items, void Function(T x) writeItem) {
    writeUInt30(items.length);
    for (var i = 0; i < items.length; i++) {
      writeItem(items[i]);
    }
  }

  /// Write [items] filtering them by [T].
  void writeList2<T>(List<Object> items, void Function(T x) writeItem) {
    var typedItems = items.whereType<T>().toList();
    writeUInt30(typedItems.length);
    for (var i = 0; i < typedItems.length; i++) {
      writeItem(typedItems[i]);
    }
  }

  void writeMap<K, V>(
    Map<K, V> map, {
    required void Function(K key) writeKey,
    required void Function(V value) writeValue,
  }) {
    writeUInt30(map.length);
    for (var entry in map.entries) {
      writeKey(entry.key);
      writeValue(entry.value);
    }
  }

  void writeOptionalInt64(int? value) {
    if (value != null) {
      writeBool(true);
      writeInt64(value);
    } else {
      writeBool(false);
    }
  }

  void writeOptionalObject<T>(T? object, void Function(T x) write) {
    if (object != null) {
      writeBool(true);
      write(object);
    } else {
      writeBool(false);
    }
  }

  void writeOptionalStringUtf8(String? value) {
    if (value != null) {
      writeBool(true);
      writeStringUtf8(value);
    } else {
      writeBool(false);
    }
  }

  void writeOptionalUInt30(int? value) {
    if (value != null) {
      writeBool(true);
      writeUInt30(value);
    } else {
      writeBool(false);
    }
  }

  /// Write the [value] as UTF8 encoded byte array.
  void writeStringUtf8(String value) {
    var bytes = const Utf8Encoder().convert(value);
    writeUint8List(bytes);
  }

  void writeStringUtf8Iterable(Iterable<String> items) {
    writeUInt30(items.length);
    for (var item in items) {
      writeStringUtf8(item);
    }
  }

  @pragma("vm:prefer-inline")
  void writeUInt30(int value) {
    assert(value >= 0 && value >> 30 == 0);
    if (value < 0x80) {
      _addByte(value);
    } else if (value < 0x4000) {
      _addByte2((value >> 8) | 0x80, value & 0xFF);
    } else {
      _addByte4(
        (value >> 24) | 0xC0,
        (value >> 16) & 0xFF,
        (value >> 8) & 0xFF,
        value & 0xFF,
      );
    }
  }

  void writeUint30List(List<int> values) {
    var length = values.length;
    writeUInt30(length);
    for (var i = 0; i < length; i++) {
      writeUInt30(values[i]);
    }
  }

  void writeUInt32(int value) {
    _addByte4(
      (value >> 24) & 0xFF,
      (value >> 16) & 0xFF,
      (value >> 8) & 0xFF,
      value & 0xFF,
    );
  }

  void writeUint8List(Uint8List bytes) {
    writeUInt30(bytes.length);
    writeBytes(bytes);
  }

  void writeUri(Uri uri) {
    var uriStr = uri.toString();
    writeStringUtf8(uriStr);
  }

  @pragma("vm:prefer-inline")
  void _addByte(int byte) {
    _buffer[_length++] = byte;
    if (_length == _SIZE) {
      _builder.add(_buffer);
      _buffer = Uint8List(_SIZE);
      _length = 0;
    }
  }

  @pragma("vm:prefer-inline")
  void _addByte2(int byte1, int byte2) {
    if (_length < _SAFE_LENGTH) {
      _buffer[_length++] = byte1;
      _buffer[_length++] = byte2;
    } else {
      _addByte(byte1);
      _addByte(byte2);
    }
  }

  @pragma("vm:prefer-inline")
  void _addByte4(int byte1, int byte2, int byte3, int byte4) {
    if (_length < _SAFE_LENGTH) {
      _buffer[_length++] = byte1;
      _buffer[_length++] = byte2;
      _buffer[_length++] = byte3;
      _buffer[_length++] = byte4;
    } else {
      _addByte(byte1);
      _addByte(byte2);
      _addByte(byte3);
      _addByte(byte4);
    }
  }
}
