// Copyright (c) 2011, 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 protobuf;

/// Writer used for converting [GeneratedMessage]s into binary
/// representation.
///
/// Note that it is impossible to serialize protobuf messages using a one pass
/// streaming serialization as some values are serialized using
/// length-delimited representation, which means that they are represented as
/// a varint encoded length followed by specified number of bytes of data.
///
/// Due to this [CodedBufferWritter] maintains two output buffers:
/// [_outputChunks] which contains all continuously written bytes and
/// [_splices] which describes additional bytes to splice in-between
/// [_outputChunks] bytes.
///
class CodedBufferWriter {
  /// Array of splices representing the data written into the writer.
  /// Each element might be one of:
  ///   * a TypedData object - represents a sequence of bytes that need to be
  ///                          emitted into the result as-is;
  ///   * a positive integer - a number of bytes to copy from [_outputChunks]
  ///                          into resulting buffer;
  ///   * a non-positive integer - a positive number that needs to be emitted
  ///                              into result buffer as a varint;
  final List<dynamic> _splices = <dynamic>[];

  /// Number of bytes written into [_outputChunk] and [_outputChunks] since
  /// the last splice was recorded.
  int _lastSplicePos = 0;

  /// Size of the [_outputChunk].
  static const _chunkLength = 512;

  /// Current chunk used to write data into. Once it is full it is
  /// pushed into [_outputChunks] and a new one is allocated.
  Uint8List _outputChunk;

  /// Number of bytes written into the [_outputChunk].
  int _bytesInChunk = 0;

  /// ByteData pointing to [_outputChunk]. Used to write primitive values
  /// more efficiently.
  ByteData _outputChunkAsByteData;

  /// Array of pairs <Uint8List chunk, int bytesInChunk> - chunks are
  /// pushed into this array once they are full.
  final List<dynamic> _outputChunks = <dynamic>[];

  /// Total amount of bytes used in all chunks.
  int _outputChunksBytes = 0;

  /// Total amount of bytes written into this writer.
  int _bytesTotal = 0;
  int get lengthInBytes => _bytesTotal;

  CodedBufferWriter() {
    // Initialize [_outputChunk].
    _commitChunk(true);
  }

  void writeField(int fieldNumber, int fieldType, fieldValue) {
    final valueType = fieldType & ~0x07;

    if ((fieldType & PbFieldType._PACKED_BIT) != 0) {
      if (!fieldValue.isEmpty) {
        _writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
        final mark = _startLengthDelimited();
        for (var value in fieldValue) {
          _writeValueAs(valueType, value);
        }
        _endLengthDelimited(mark);
      }
      return;
    }

    final wireFormat = _wireTypes[_valueTypeIndex(valueType)];

    if ((fieldType & PbFieldType._MAP_BIT) != 0) {
      final keyWireFormat =
          _wireTypes[_valueTypeIndex(fieldValue.keyFieldType)];
      final valueWireFormat =
          _wireTypes[_valueTypeIndex(fieldValue.valueFieldType)];

      fieldValue.forEach((key, value) {
        _writeTag(fieldNumber, WIRETYPE_LENGTH_DELIMITED);
        final mark = _startLengthDelimited();
        _writeValue(
            PbMap._keyFieldNumber, fieldValue.keyFieldType, key, keyWireFormat);
        _writeValue(PbMap._valueFieldNumber, fieldValue.valueFieldType, value,
            valueWireFormat);
        _endLengthDelimited(mark);
      });
      return;
    }

    if ((fieldType & PbFieldType._REPEATED_BIT) != 0) {
      for (var i = 0; i < fieldValue.length; i++) {
        _writeValue(fieldNumber, valueType, fieldValue[i], wireFormat);
      }
      return;
    }
    _writeValue(fieldNumber, valueType, fieldValue, wireFormat);
  }

  Uint8List toBuffer() {
    var result = Uint8List(_bytesTotal);
    writeTo(result);
    return result;
  }

  /// Serializes everything written to this writer so far to [buffer], starting
  /// from [offset] in [buffer]. Returns `true` on success.
  bool writeTo(Uint8List buffer, [int offset = 0]) {
    if (buffer.length - offset < _bytesTotal) {
      return false;
    }

    // Move the current output chunk into _outputChunks and commit the current
    // splice for uniformity.
    _commitChunk(false);
    _commitSplice();

    var outPos = offset; // Output position in the buffer.
    var chunkIndex = 0, chunkPos = 0; // Position within _outputChunks.
    for (var i = 0; i < _splices.length; i++) {
      final action = _splices[i];
      if (action is int) {
        if (action <= 0) {
          // action is a positive varint to be emitted into the output buffer.
          var v = 0 - action; // Note: 0 - action to avoid -0.0 in JS.
          while (v >= 0x80) {
            buffer[outPos++] = 0x80 | (v & 0x7f);
            v >>= 7;
          }
          buffer[outPos++] = v;
        } else {
          // action is an amount of bytes to copy from _outputChunks into the
          // buffer.
          var bytesToCopy = action;
          while (bytesToCopy > 0) {
            final Uint8List chunk = _outputChunks[chunkIndex];
            final int bytesInChunk = _outputChunks[chunkIndex + 1];

            // Copy at most bytesToCopy bytes from the current chunk.
            final leftInChunk = bytesInChunk - chunkPos;
            final bytesToCopyFromChunk =
                leftInChunk > bytesToCopy ? bytesToCopy : leftInChunk;
            final endPos = chunkPos + bytesToCopyFromChunk;
            while (chunkPos < endPos) {
              buffer[outPos++] = chunk[chunkPos++];
            }
            bytesToCopy -= bytesToCopyFromChunk;

            // Move to the next chunk if the current one is exhausted.
            if (chunkPos == bytesInChunk) {
              chunkIndex += 2;
              chunkPos = 0;
            }
          }
        }
      } else {
        // action is a TypedData containing bytes to emit into the output
        // buffer.
        outPos = _copyInto(buffer, outPos, action);
      }
    }

    return true;
  }

  /// Move the current [_outputChunk] into [_outputChunks].
  ///
  /// If [allocateNew] is [true] then allocate a new chunk, otherwise
  /// set [_outputChunk] to null.
  void _commitChunk(bool allocateNew) {
    if (_bytesInChunk != 0) {
      _outputChunks.add(_outputChunk);
      _outputChunks.add(_bytesInChunk);
      _outputChunksBytes += _bytesInChunk;
    }

    if (allocateNew) {
      _outputChunk = Uint8List(_chunkLength);
      _bytesInChunk = 0;
      _outputChunkAsByteData = ByteData.view(_outputChunk.buffer);
    } else {
      _outputChunk = _outputChunkAsByteData = null;
      _bytesInChunk = 0;
    }
  }

  /// Check if [count] bytes would fit into the current chunk. If they will
  /// not then allocate a new [_outputChunk].
  ///
  /// [count] is assumed to be small enough to fit into the newly allocated
  /// chunk.
  void _ensureBytes(int count) {
    if ((_bytesInChunk + count) > _chunkLength) {
      _commitChunk(true);
    }
  }

  /// Record number of bytes written into output chunks since last splice.
  ///
  /// This is used before reserving space for an unknown varint splice or
  /// adding a TypedData array splice.
  void _commitSplice() {
    final pos = _bytesInChunk + _outputChunksBytes;
    final bytes = pos - _lastSplicePos;
    if (bytes > 0) {
      _splices.add(bytes);
    }
    _lastSplicePos = pos;
  }

  /// Add TypedData splice - these bytes would be directly copied into the
  /// output buffer by [writeTo].
  void writeRawBytes(TypedData value) {
    _commitSplice();
    _splices.add(value);
    _bytesTotal += value.lengthInBytes;
  }

  /// Start writing a length-delimited data.
  ///
  /// This reserves the space for varint splice in the splices array and
  /// return its index. Once the writing is finished [_endLengthDelimited]
  /// would be called with this index - which would put the actual amount
  /// of bytes written into the reserved slice space.
  int _startLengthDelimited() {
    _commitSplice();
    var index = _splices.length;
    // Reserve a space for a splice and use it to record the current number of
    // bytes written so that we can compute the length of data later in
    // _endLengthDelimited.
    _splices.add(_bytesTotal);
    return index;
  }

  void _endLengthDelimited(int index) {
    final int writtenSizeInBytes = _bytesTotal - _splices[index];
    // Note: 0 - writtenSizeInBytes to avoid -0.0 in JavaScript.
    _splices[index] = 0 - writtenSizeInBytes;
    _bytesTotal += _varint32LengthInBytes(writtenSizeInBytes);
  }

  int _varint32LengthInBytes(int value) {
    value &= 0xFFFFFFFF;
    if (value < 0x80) return 1;
    if (value < 0x4000) return 2;
    if (value < 0x200000) return 3;
    if (value < 0x10000000) return 4;
    return 5;
  }

  void _writeVarint32(int value) {
    _ensureBytes(5);
    var i = _bytesInChunk;
    while (value >= 0x80) {
      _outputChunk[i++] = 0x80 | (value & 0x7f);
      value >>= 7;
    }
    _outputChunk[i++] = value;
    _bytesTotal += (i - _bytesInChunk);
    _bytesInChunk = i;
  }

  void _writeVarint64(Int64 value) {
    _ensureBytes(10);
    var i = _bytesInChunk;
    var lo = value.toUnsigned(32).toInt();
    var hi = (value >> 32).toUnsigned(32).toInt();
    while (hi > 0 || lo >= 0x80) {
      _outputChunk[i++] = 0x80 | (lo & 0x7f);
      lo = (lo >> 7) | ((hi & 0x7f) << 25);
      hi >>= 7;
    }
    _outputChunk[i++] = lo;
    _bytesTotal += (i - _bytesInChunk);
    _bytesInChunk = i;
  }

  void _writeDouble(double value) {
    if (value.isNaN) {
      _writeInt32(0x00000000);
      _writeInt32(0x7ff80000);
      return;
    }
    _ensureBytes(8);
    _outputChunkAsByteData.setFloat64(_bytesInChunk, value, Endian.little);
    _bytesInChunk += 8;
    _bytesTotal += 8;
  }

  void _writeFloat(double value) {
    const MIN_FLOAT_DENORM = 1.401298464324817E-45;
    const MAX_FLOAT = 3.4028234663852886E38;
    if (value.isNaN) {
      _writeInt32(0x7fc00000);
    } else if (value.abs() < MIN_FLOAT_DENORM) {
      _writeInt32(value.isNegative ? 0x80000000 : 0x00000000);
    } else if (value.isInfinite || value.abs() > MAX_FLOAT) {
      _writeInt32(value.isNegative ? 0xff800000 : 0x7f800000);
    } else {
      const sz = 4;
      _ensureBytes(sz);
      _outputChunkAsByteData.setFloat32(_bytesInChunk, value, Endian.little);
      _bytesInChunk += sz;
      _bytesTotal += sz;
    }
  }

  void _writeInt32(int value) {
    const sizeInBytes = 4;
    _ensureBytes(sizeInBytes);
    _outputChunkAsByteData.setInt32(
        _bytesInChunk, value & 0xFFFFFFFF, Endian.little);
    _bytesInChunk += sizeInBytes;
    _bytesTotal += sizeInBytes;
  }

  void _writeInt64(Int64 value) {
    _writeInt32(value.toUnsigned(32).toInt());
    _writeInt32((value >> 32).toUnsigned(32).toInt());
  }

  void _writeValueAs(int valueType, dynamic value) {
    switch (valueType) {
      case PbFieldType._BOOL_BIT:
        _writeVarint32(value ? 1 : 0);
        break;
      case PbFieldType._BYTES_BIT:
        _writeBytesNoTag(
            value is TypedData ? value : Uint8List.fromList(value));
        break;
      case PbFieldType._STRING_BIT:
        _writeBytesNoTag(_utf8.encode(value));
        break;
      case PbFieldType._DOUBLE_BIT:
        _writeDouble(value);
        break;
      case PbFieldType._FLOAT_BIT:
        _writeFloat(value);
        break;
      case PbFieldType._ENUM_BIT:
        _writeVarint32(value.value & 0xffffffff);
        break;
      case PbFieldType._GROUP_BIT:
        value.writeToCodedBufferWriter(this);
        break;
      case PbFieldType._INT32_BIT:
        _writeVarint64(Int64(value));
        break;
      case PbFieldType._INT64_BIT:
        _writeVarint64(value);
        break;
      case PbFieldType._SINT32_BIT:
        _writeVarint32(_encodeZigZag32(value));
        break;
      case PbFieldType._SINT64_BIT:
        _writeVarint64(_encodeZigZag64(value));
        break;
      case PbFieldType._UINT32_BIT:
        _writeVarint32(value);
        break;
      case PbFieldType._UINT64_BIT:
        _writeVarint64(value);
        break;
      case PbFieldType._FIXED32_BIT:
        _writeInt32(value);
        break;
      case PbFieldType._FIXED64_BIT:
        _writeInt64(value);
        break;
      case PbFieldType._SFIXED32_BIT:
        _writeInt32(value);
        break;
      case PbFieldType._SFIXED64_BIT:
        _writeInt64(value);
        break;
      case PbFieldType._MESSAGE_BIT:
        final mark = _startLengthDelimited();
        value.writeToCodedBufferWriter(this);
        _endLengthDelimited(mark);
        break;
    }
  }

  void _writeBytesNoTag(dynamic value) {
    writeInt32NoTag(value.length);
    writeRawBytes(value);
  }

  void _writeTag(int fieldNumber, int wireFormat) {
    writeInt32NoTag(makeTag(fieldNumber, wireFormat));
  }

  void _writeValue(
      int fieldNumber, int valueType, dynamic value, int wireFormat) {
    _writeTag(fieldNumber, wireFormat);
    _writeValueAs(valueType, value);
    if (valueType == PbFieldType._GROUP_BIT) {
      _writeTag(fieldNumber, WIRETYPE_END_GROUP);
    }
  }

  void writeInt32NoTag(int value) {
    _writeVarint32(value & 0xFFFFFFFF);
  }

  /// Copy bytes from the given typed data array into the output buffer.
  ///
  /// Has a specialization for Uint8List for performance.
  int _copyInto(Uint8List buffer, int pos, TypedData value) {
    if (value is Uint8List) {
      var len = value.length;
      for (var j = 0; j < len; j++) {
        buffer[pos++] = value[j];
      }
      return pos;
    } else {
      var len = value.lengthInBytes;
      var u8 = Uint8List.view(
          value.buffer, value.offsetInBytes, value.lengthInBytes);
      for (var j = 0; j < len; j++) {
        buffer[pos++] = u8[j];
      }
      return pos;
    }
  }

  /// This function maps a power-of-2 value (2^0 .. 2^31) to a unique value
  /// in the 0..31 range.
  ///
  /// For more details see "Using de Bruijn Sequences to Index a 1 in
  /// a Computer Word"[1]
  ///
  /// Note: this is guaranteed to work after compilation to JavaScript
  /// where multiplication becomes a floating point multiplication.
  ///
  /// [1] http://supertech.csail.mit.edu/papers/debruijn.pdf
  static int _valueTypeIndex(int powerOf2) =>
      ((0x077CB531 * powerOf2) >> 27) & 31;

  /// Precomputed indices for all FbFieldType._XYZ_BIT values:
  ///
  ///    _XYZ_BIT_INDEX = _valueTypeIndex(FbFieldType._XYZ_BIT)
  ///
  static const _BOOL_BIT_INDEX = 14;
  static const _BYTES_BIT_INDEX = 29;
  static const _STRING_BIT_INDEX = 27;
  static const _DOUBLE_BIT_INDEX = 23;
  static const _FLOAT_BIT_INDEX = 15;
  static const _ENUM_BIT_INDEX = 31;
  static const _GROUP_BIT_INDEX = 30;
  static const _INT32_BIT_INDEX = 28;
  static const _INT64_BIT_INDEX = 25;
  static const _SINT32_BIT_INDEX = 18;
  static const _SINT64_BIT_INDEX = 5;
  static const _UINT32_BIT_INDEX = 11;
  static const _UINT64_BIT_INDEX = 22;
  static const _FIXED32_BIT_INDEX = 13;
  static const _FIXED64_BIT_INDEX = 26;
  static const _SFIXED32_BIT_INDEX = 21;
  static const _SFIXED64_BIT_INDEX = 10;
  static const _MESSAGE_BIT_INDEX = 20;

  /// Mapping from value types to wire-types indexed by _valueTypeIndex(...).
  static final Uint8List _wireTypes = Uint8List(32)
    ..[_BOOL_BIT_INDEX] = WIRETYPE_VARINT
    ..[_BYTES_BIT_INDEX] = WIRETYPE_LENGTH_DELIMITED
    ..[_STRING_BIT_INDEX] = WIRETYPE_LENGTH_DELIMITED
    ..[_DOUBLE_BIT_INDEX] = WIRETYPE_FIXED64
    ..[_FLOAT_BIT_INDEX] = WIRETYPE_FIXED32
    ..[_ENUM_BIT_INDEX] = WIRETYPE_VARINT
    ..[_GROUP_BIT_INDEX] = WIRETYPE_START_GROUP
    ..[_INT32_BIT_INDEX] = WIRETYPE_VARINT
    ..[_INT64_BIT_INDEX] = WIRETYPE_VARINT
    ..[_SINT32_BIT_INDEX] = WIRETYPE_VARINT
    ..[_SINT64_BIT_INDEX] = WIRETYPE_VARINT
    ..[_UINT32_BIT_INDEX] = WIRETYPE_VARINT
    ..[_UINT64_BIT_INDEX] = WIRETYPE_VARINT
    ..[_FIXED32_BIT_INDEX] = WIRETYPE_FIXED32
    ..[_FIXED64_BIT_INDEX] = WIRETYPE_FIXED64
    ..[_SFIXED32_BIT_INDEX] = WIRETYPE_FIXED32
    ..[_SFIXED64_BIT_INDEX] = WIRETYPE_FIXED64
    ..[_MESSAGE_BIT_INDEX] = WIRETYPE_LENGTH_DELIMITED;
}

int _encodeZigZag32(int value) => (value << 1) ^ (value >> 31);
Int64 _encodeZigZag64(Int64 value) => (value << 1) ^ (value >> 63);
