/**
 * @fileoverview Implements Writer for writing data as the binary wire format
 * bytes array.
 */
goog.module('protobuf.binary.Writer');

const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
const ByteString = goog.require('protobuf.ByteString');
const Int64 = goog.require('protobuf.Int64');
const WireType = goog.require('protobuf.binary.WireType');
const {POLYFILL_TEXT_ENCODING, checkFieldNumber, checkTypeUnsignedInt32, checkWireType} = goog.require('protobuf.internal.checks');
const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays');
const {createTag, getTagLength} = goog.require('protobuf.binary.tag');
const {encode} = goog.require('protobuf.binary.textencoding');

/**
 * Returns a valid utf-8 encoder function based on TextEncoder if available or
 * a polyfill.
 * Some of the environments we run in do not have TextEncoder defined.
 * TextEncoder is faster than our polyfill so we prefer it over the polyfill.
 * @return {function(string):!Uint8Array}
 */
function getEncoderFunction() {
  if (goog.global['TextEncoder']) {
    const textEncoder = new goog.global['TextEncoder']('utf-8');
    return s => s.length === 0 ? new Uint8Array(0) : textEncoder.encode(s);
  }
  if (POLYFILL_TEXT_ENCODING) {
    return encode;
  } else {
    throw new Error(
        'TextEncoder is missing. ' +
        'Enable protobuf.defines.POLYFILL_TEXT_ENCODING');
  }
}

/** @const {function(string): !Uint8Array} */
const encoderFunction = getEncoderFunction();

/**
 * Writer provides methods for encoding all protobuf supported type into a
 * binary format bytes array.
 * Check https://developers.google.com/protocol-buffers/docs/encoding for binary
 * format definition.
 * @final
 * @package
 */
class Writer {
  constructor() {
    /**
     * Blocks of data that needs to be serialized. After writing all the data,
     * the blocks are concatenated into a single Uint8Array.
     * @private {!Array<!Uint8Array>}
     */
    this.blocks_ = [];

    /**
     * A buffer for writing varint data (tag number + field number for each
     * field, int32, uint32 etc.). Before writing a non-varint data block
     * (string, fixed32 etc.), the buffer is appended to the block array as a
     * new block, and a new buffer is started.
     *
     * We could've written each varint as a new block instead of writing
     * multiple varints in this buffer. But this will increase the number of
     * blocks, and concatenating many small blocks is slower than concatenating
     * few large blocks.
     *
     * TODO: Experiment with writing data in a fixed-length
     * Uint8Array instead of using a growing buffer.
     *
     * @private {!Array<number>}
     */
    this.currentBuffer_ = [];
  }

  /**
   * Converts the encoded data into a Uint8Array.
   * The writer is also reset.
   * @return {!ArrayBuffer}
   */
  getAndResetResultBuffer() {
    this.closeAndStartNewBuffer_();
    const result = concatenateByteArrays(this.blocks_);
    this.blocks_ = [];
    return result.buffer;
  }

  /**
   * Encodes a (field number, wire type) tuple into a wire-format field header.
   * @param {number} fieldNumber
   * @param {!WireType} wireType
   */
  writeTag(fieldNumber, wireType) {
    checkFieldNumber(fieldNumber);
    checkWireType(wireType);
    const tag = createTag(wireType, fieldNumber);
    this.writeUnsignedVarint32_(tag);
  }

  /**
   * Appends the current buffer into the blocks array and starts a new buffer.
   * @private
   */
  closeAndStartNewBuffer_() {
    this.blocks_.push(new Uint8Array(this.currentBuffer_));
    this.currentBuffer_ = [];
  }

  /**
   * Encodes a 32-bit integer into its wire-format varint representation and
   * stores it in the buffer.
   * @param {number} value
   * @private
   */
  writeUnsignedVarint32_(value) {
    checkTypeUnsignedInt32(value);
    while (value > 0x7f) {
      this.currentBuffer_.push((value & 0x7f) | 0x80);
      value = value >>> 7;
    }
    this.currentBuffer_.push(value);
  }

  /****************************************************************************
   *                        OPTIONAL METHODS
   ****************************************************************************/

  /**
   * Writes a boolean value field to the buffer as a varint.
   * @param {boolean} value
   * @private
   */
  writeBoolValue_(value) {
    this.currentBuffer_.push(value ? 1 : 0);
  }

  /**
   * Writes a boolean value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {boolean} value
   */
  writeBool(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeBoolValue_(value);
  }

  /**
   * Writes a bytes value field to the buffer as a length delimited field.
   * @param {number} fieldNumber
   * @param {!ByteString} value
   */
  writeBytes(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.DELIMITED);
    const buffer = value.toArrayBuffer();
    this.writeUnsignedVarint32_(buffer.byteLength);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a double value field to the buffer without tag.
   * @param {number} value
   * @private
   */
  writeDoubleValue_(value) {
    const buffer = new ArrayBuffer(8);
    const view = new DataView(buffer);
    view.setFloat64(0, value, true);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a double value field to the buffer.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeDouble(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.FIXED64);
    this.writeDoubleValue_(value);
  }

  /**
   * Writes a fixed32 value field to the buffer without tag.
   * @param {number} value
   * @private
   */
  writeFixed32Value_(value) {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setUint32(0, value, true);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a fixed32 value field to the buffer.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeFixed32(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.FIXED32);
    this.writeFixed32Value_(value);
  }

  /**
   * Writes a float value field to the buffer without tag.
   * @param {number} value
   * @private
   */
  writeFloatValue_(value) {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setFloat32(0, value, true);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a float value field to the buffer.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeFloat(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.FIXED32);
    this.writeFloatValue_(value);
  }

  /**
   * Writes a int32 value field to the buffer as a varint without tag.
   * @param {number} value
   * @private
   */
  writeInt32Value_(value) {
    if (value >= 0) {
      this.writeVarint64_(0, value);
    } else {
      this.writeVarint64_(0xFFFFFFFF, value);
    }
  }

  /**
   * Writes a int32 value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeInt32(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeInt32Value_(value);
  }

  /**
   * Writes a int64 value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {!Int64} value
   */
  writeInt64(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeVarint64_(value.getHighBits(), value.getLowBits());
  }

  /**
   * Writes a sfixed32 value field to the buffer.
   * @param {number} value
   * @private
   */
  writeSfixed32Value_(value) {
    const buffer = new ArrayBuffer(4);
    const view = new DataView(buffer);
    view.setInt32(0, value, true);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a sfixed32 value field to the buffer.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeSfixed32(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.FIXED32);
    this.writeSfixed32Value_(value);
  }

  /**
   * Writes a sfixed64 value field to the buffer without tag.
   * @param {!Int64} value
   * @private
   */
  writeSfixed64Value_(value) {
    const buffer = new ArrayBuffer(8);
    const view = new DataView(buffer);
    view.setInt32(0, value.getLowBits(), true);
    view.setInt32(4, value.getHighBits(), true);
    this.writeRaw_(buffer);
  }

  /**
   * Writes a sfixed64 value field to the buffer.
   * @param {number} fieldNumber
   * @param {!Int64} value
   */
  writeSfixed64(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.FIXED64);
    this.writeSfixed64Value_(value);
  }

  /**
   * Writes a sfixed64 value field to the buffer.
   * @param {number} fieldNumber
   */
  writeStartGroup(fieldNumber) {
    this.writeTag(fieldNumber, WireType.START_GROUP);
  }

  /**
   * Writes a sfixed64 value field to the buffer.
   * @param {number} fieldNumber
   */
  writeEndGroup(fieldNumber) {
    this.writeTag(fieldNumber, WireType.END_GROUP);
  }

  /**
   * Writes a uint32 value field to the buffer as a varint without tag.
   * @param {number} value
   * @private
   */
  writeUint32Value_(value) {
    this.writeVarint64_(0, value);
  }

  /**
   * Writes a uint32 value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeUint32(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeUint32Value_(value);
  }

  /**
   * Writes the bits of a 64 bit number to the buffer as a varint.
   * @param {number} highBits
   * @param {number} lowBits
   * @private
   */
  writeVarint64_(highBits, lowBits) {
    for (let i = 0; i < 28; i = i + 7) {
      const shift = lowBits >>> i;
      const hasNext = !((shift >>> 7) === 0 && highBits === 0);
      const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
      this.currentBuffer_.push(byte);
      if (!hasNext) {
        return;
      }
    }

    const splitBits = ((lowBits >>> 28) & 0x0F) | ((highBits & 0x07) << 4);
    const hasMoreBits = !((highBits >> 3) === 0);
    this.currentBuffer_.push(
        (hasMoreBits ? splitBits | 0x80 : splitBits) & 0xFF);

    if (!hasMoreBits) {
      return;
    }

    for (let i = 3; i < 31; i = i + 7) {
      const shift = highBits >>> i;
      const hasNext = !((shift >>> 7) === 0);
      const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
      this.currentBuffer_.push(byte);
      if (!hasNext) {
        return;
      }
    }

    this.currentBuffer_.push((highBits >>> 31) & 0x01);
  }

  /**
   * Writes a sint32 value field to the buffer as a varint without tag.
   * @param {number} value
   * @private
   */
  writeSint32Value_(value) {
    value = (value << 1) ^ (value >> 31);
    this.writeVarint64_(0, value);
  }

  /**
   * Writes a sint32 value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {number} value
   */
  writeSint32(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeSint32Value_(value);
  }

  /**
   * Writes a sint64 value field to the buffer as a varint without tag.
   * @param {!Int64} value
   * @private
   */
  writeSint64Value_(value) {
    const highBits = value.getHighBits();
    const lowBits = value.getLowBits();

    const sign = highBits >> 31;
    const encodedLowBits = (lowBits << 1) ^ sign;
    const encodedHighBits = ((highBits << 1) | (lowBits >>> 31)) ^ sign;
    this.writeVarint64_(encodedHighBits, encodedLowBits);
  }

  /**
   * Writes a sint64 value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {!Int64} value
   */
  writeSint64(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.VARINT);
    this.writeSint64Value_(value);
  }

  /**
   * Writes a string value field to the buffer as a varint.
   * @param {number} fieldNumber
   * @param {string} value
   */
  writeString(fieldNumber, value) {
    this.writeTag(fieldNumber, WireType.DELIMITED);
    const array = encoderFunction(value);
    this.writeUnsignedVarint32_(array.length);
    this.closeAndStartNewBuffer_();
    this.blocks_.push(array);
  }

  /**
   * Writes raw bytes to the buffer.
   * @param {!ArrayBuffer} arrayBuffer
   * @private
   */
  writeRaw_(arrayBuffer) {
    this.closeAndStartNewBuffer_();
    this.blocks_.push(new Uint8Array(arrayBuffer));
  }

  /**
   * Writes raw bytes to the buffer.
   * @param {!BufferDecoder} bufferDecoder
   * @param {number} start
   * @param {!WireType} wireType
   * @param {number} fieldNumber
   * @package
   */
  writeBufferDecoder(bufferDecoder, start, wireType, fieldNumber) {
    this.closeAndStartNewBuffer_();
    const dataLength =
        getTagLength(bufferDecoder, start, wireType, fieldNumber);
    this.blocks_.push(
        bufferDecoder.subBufferDecoder(start, dataLength).asUint8Array());
  }

  /**
   * Write the whole bytes as a length delimited field.
   * @param {number} fieldNumber
   * @param {!ArrayBuffer} arrayBuffer
   */
  writeDelimited(fieldNumber, arrayBuffer) {
    this.writeTag(fieldNumber, WireType.DELIMITED);
    this.writeUnsignedVarint32_(arrayBuffer.byteLength);
    this.writeRaw_(arrayBuffer);
  }

  /****************************************************************************
   *                        REPEATED METHODS
   ****************************************************************************/

  /**
   * Writes repeated boolean values to the buffer as unpacked varints.
   * @param {number} fieldNumber
   * @param {!Array<boolean>} values
   */
  writeRepeatedBool(fieldNumber, values) {
    values.forEach(val => this.writeBool(fieldNumber, val));
  }

  /**
   * Writes repeated boolean values to the buffer as packed varints.
   * @param {number} fieldNumber
   * @param {!Array<boolean>} values
   */
  writePackedBool(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeBoolValue_(val), 1);
  }

  /**
   * Writes repeated double values to the buffer as unpacked fixed64.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedDouble(fieldNumber, values) {
    values.forEach(val => this.writeDouble(fieldNumber, val));
  }

  /**
   * Writes repeated double values to the buffer as packed fixed64.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedDouble(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeDoubleValue_(val), 8);
  }

  /**
   * Writes repeated fixed32 values to the buffer as unpacked fixed32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedFixed32(fieldNumber, values) {
    values.forEach(val => this.writeFixed32(fieldNumber, val));
  }

  /**
   * Writes repeated fixed32 values to the buffer as packed fixed32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedFixed32(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeFixed32Value_(val), 4);
  }

  /**
   * Writes repeated float values to the buffer as unpacked fixed64.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedFloat(fieldNumber, values) {
    values.forEach(val => this.writeFloat(fieldNumber, val));
  }

  /**
   * Writes repeated float values to the buffer as packed fixed64.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedFloat(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeFloatValue_(val), 4);
  }

  /**
   * Writes repeated int32 values to the buffer as unpacked int32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedInt32(fieldNumber, values) {
    values.forEach(val => this.writeInt32(fieldNumber, val));
  }

  /**
   * Writes repeated int32 values to the buffer as packed int32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedInt32(fieldNumber, values) {
    this.writeVariablePacked_(
        fieldNumber, values, (writer, val) => writer.writeInt32Value_(val));
  }

  /**
   * Writes repeated int64 values to the buffer as unpacked varint.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writeRepeatedInt64(fieldNumber, values) {
    values.forEach(val => this.writeInt64(fieldNumber, val));
  }

  /**
   * Writes repeated int64 values to the buffer as packed varint.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writePackedInt64(fieldNumber, values) {
    this.writeVariablePacked_(
        fieldNumber, values,
        (writer, val) =>
            writer.writeVarint64_(val.getHighBits(), val.getLowBits()));
  }

  /**
   * Writes repeated sfixed32 values to the buffer as unpacked fixed32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedSfixed32(fieldNumber, values) {
    values.forEach(val => this.writeSfixed32(fieldNumber, val));
  }

  /**
   * Writes repeated sfixed32 values to the buffer as packed fixed32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedSfixed32(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeSfixed32Value_(val), 4);
  }

  /**
   * Writes repeated sfixed64 values to the buffer as unpacked fixed64.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writeRepeatedSfixed64(fieldNumber, values) {
    values.forEach(val => this.writeSfixed64(fieldNumber, val));
  }

  /**
   * Writes repeated sfixed64 values to the buffer as packed fixed64.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writePackedSfixed64(fieldNumber, values) {
    this.writeFixedPacked_(
        fieldNumber, values, val => this.writeSfixed64Value_(val), 8);
  }

  /**
   * Writes repeated sint32 values to the buffer as unpacked sint32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedSint32(fieldNumber, values) {
    values.forEach(val => this.writeSint32(fieldNumber, val));
  }

  /**
   * Writes repeated sint32 values to the buffer as packed sint32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedSint32(fieldNumber, values) {
    this.writeVariablePacked_(
        fieldNumber, values, (writer, val) => writer.writeSint32Value_(val));
  }

  /**
   * Writes repeated sint64 values to the buffer as unpacked varint.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writeRepeatedSint64(fieldNumber, values) {
    values.forEach(val => this.writeSint64(fieldNumber, val));
  }

  /**
   * Writes repeated sint64 values to the buffer as packed varint.
   * @param {number} fieldNumber
   * @param {!Array<!Int64>} values
   */
  writePackedSint64(fieldNumber, values) {
    this.writeVariablePacked_(
        fieldNumber, values, (writer, val) => writer.writeSint64Value_(val));
  }

  /**
   * Writes repeated uint32 values to the buffer as unpacked uint32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writeRepeatedUint32(fieldNumber, values) {
    values.forEach(val => this.writeUint32(fieldNumber, val));
  }

  /**
   * Writes repeated uint32 values to the buffer as packed uint32.
   * @param {number} fieldNumber
   * @param {!Array<number>} values
   */
  writePackedUint32(fieldNumber, values) {
    this.writeVariablePacked_(
        fieldNumber, values, (writer, val) => writer.writeUint32Value_(val));
  }

  /**
   * Writes repeated bytes values to the buffer.
   * @param {number} fieldNumber
   * @param {!Array<!ByteString>} values
   */
  writeRepeatedBytes(fieldNumber, values) {
    values.forEach(val => this.writeBytes(fieldNumber, val));
  }

  /**
   * Writes packed fields with fixed length.
   * @param {number} fieldNumber
   * @param {!Array<T>} values
   * @param {function(T)} valueWriter
   * @param {number} entitySize
   * @template T
   * @private
   */
  writeFixedPacked_(fieldNumber, values, valueWriter, entitySize) {
    if (values.length === 0) {
      return;
    }
    this.writeTag(fieldNumber, WireType.DELIMITED);
    this.writeUnsignedVarint32_(values.length * entitySize);
    this.closeAndStartNewBuffer_();
    values.forEach(value => valueWriter(value));
  }

  /**
   * Writes packed fields with variable length.
   * @param {number} fieldNumber
   * @param {!Array<T>} values
   * @param {function(!Writer, T)} valueWriter
   * @template T
   * @private
   */
  writeVariablePacked_(fieldNumber, values, valueWriter) {
    if (values.length === 0) {
      return;
    }
    const writer = new Writer();
    values.forEach(val => valueWriter(writer, val));
    const bytes = writer.getAndResetResultBuffer();
    this.writeDelimited(fieldNumber, bytes);
  }

  /**
   * Writes repeated string values to the buffer.
   * @param {number} fieldNumber
   * @param {!Array<string>} values
   */
  writeRepeatedString(fieldNumber, values) {
    values.forEach(val => this.writeString(fieldNumber, val));
  }
}

exports = Writer;
