'use strict'

/* replacement start */
const { Buffer } = require('buffer')

/* replacement end */

const stream = require('../../lib/ours/index')
const { kReadableStreamSuiteName, kReadableStreamSuiteHasMultipleTests } = require('./symbols')
const queue = []
for (let decode = 0; decode < 2; decode++) {
  for (let uncork = 0; uncork < 2; uncork++) {
    for (let multi = 0; multi < 2; multi++) {
      queue.push([!!decode, !!uncork, !!multi])
    }
  }
}
function runTest(decode, uncork, multi) {
  return function (t) {
    t.plan(8)

    // console.log('# decode=%j uncork=%j multi=%j', decode, uncork, multi);
    let counter = 0
    let expectCount = 0
    function cnt(msg) {
      expectCount++
      const expect = expectCount
      return function (er) {
        if (er) {
          throw er
        }
        counter++
        t.equal(counter, expect)
      }
    }
    const w = new stream.Writable({
      decodeStrings: decode
    })
    w._write = function (chunk, e, cb) {
      t.ok(false, 'Should not call _write')
    }
    const expectChunks = decode
      ? [
          {
            encoding: 'buffer',
            chunk: [104, 101, 108, 108, 111, 44, 32]
          },
          {
            encoding: 'buffer',
            chunk: [119, 111, 114, 108, 100]
          },
          {
            encoding: 'buffer',
            chunk: [33]
          },
          {
            encoding: 'buffer',
            chunk: [10, 97, 110, 100, 32, 116, 104, 101, 110, 46, 46, 46]
          },
          {
            encoding: 'buffer',
            chunk: [250, 206, 190, 167, 222, 173, 190, 239, 222, 202, 251, 173]
          }
        ]
      : [
          {
            encoding: 'ascii',
            chunk: 'hello, '
          },
          {
            encoding: 'utf8',
            chunk: 'world'
          },
          {
            encoding: 'buffer',
            chunk: [33]
          },
          {
            encoding: 'binary',
            chunk: '\nand then...'
          },
          {
            encoding: 'hex',
            chunk: 'facebea7deadbeefdecafbad'
          }
        ]
    let actualChunks
    w._writev = function (chunks, cb) {
      actualChunks = chunks.map(function (chunk) {
        return {
          encoding: chunk.encoding,
          chunk: Buffer.isBuffer(chunk.chunk) ? Array.prototype.slice.call(chunk.chunk) : chunk.chunk
        }
      })
      cb()
    }
    w.cork()
    w.write('hello, ', 'ascii', cnt('hello'))
    w.write('world', 'utf8', cnt('world'))
    if (multi) {
      w.cork()
    }
    w.write(Buffer.from('!'), 'buffer', cnt('!'))
    w.write('\nand then...', 'binary', cnt('and then'))
    if (multi) {
      w.uncork()
    }
    w.write('facebea7deadbeefdecafbad', 'hex', cnt('hex'))
    if (uncork) {
      w.uncork()
    }
    w.end(cnt('end'))
    w.on('finish', function () {
      // make sure finish comes after all the write cb
      cnt('finish')()
      t.deepEqual(expectChunks, actualChunks)
    })
  }
}
module.exports = function (test) {
  for (let i = 0; i < queue.length; i++) {
    const tr = queue[i]
    test('round ' + i, runTest(tr[0], tr[1], tr[2]))
  }
}
module.exports[kReadableStreamSuiteName] = 'stream-writev'
module.exports[kReadableStreamSuiteHasMultipleTests] = true
