'use strict';

const DuplexStream = require('readable-stream').Duplex;
const inherits = require('inherits');
const BufferList = require('./BufferList');

function BufferListStream(callback) {
  if (!(this instanceof BufferListStream)) {
    return new BufferListStream(callback);
  }

  if (typeof callback === 'function') {
    this._callback = callback;

    const piper = function piper(err) {
      if (this._callback) {
        this._callback(err);
        this._callback = null;
      }
    }.bind(this);

    this.on('pipe', function onPipe(src) {
      src.on('error', piper);
    });
    this.on('unpipe', function onUnpipe(src) {
      src.removeListener('error', piper);
    });

    callback = null;
  }

  BufferList._init.call(this, callback);
  DuplexStream.call(this);
}

inherits(BufferListStream, DuplexStream);
Object.assign(BufferListStream.prototype, BufferList.prototype);

BufferListStream.prototype._new = function _new(callback) {
  return new BufferListStream(callback);
};

BufferListStream.prototype._write = function _write(buf, encoding, callback) {
  this._appendBuffer(buf);

  if (typeof callback === 'function') {
    callback();
  }
};

BufferListStream.prototype._read = function _read(size) {
  if (!this.length) {
    return this.push(null);
  }

  size = Math.min(size, this.length);
  this.push(this.slice(0, size));
  this.consume(size);
};

BufferListStream.prototype.end = function end(chunk) {
  DuplexStream.prototype.end.call(this, chunk);

  if (this._callback) {
    this._callback(null, this.slice());
    this._callback = null;
  }
};

BufferListStream.prototype._destroy = function _destroy(err, cb) {
  this._bufs.length = 0;
  this.length = 0;
  cb(err);
};

BufferListStream.prototype._isBufferList = function _isBufferList(b) {
  return (
    b instanceof BufferListStream ||
    b instanceof BufferList ||
    BufferListStream.isBufferList(b)
  );
};

BufferListStream.isBufferList = BufferList.isBufferList;

module.exports = BufferListStream;
module.exports.BufferListStream = BufferListStream;
module.exports.BufferList = BufferList;