var tape = require('tape')
var through = require('through2')
var concat = require('concat-stream')
var net = require('net')
var duplexify = require('./')

var HELLO_WORLD = (Buffer.from && Buffer.from !== Uint8Array.from)
 ? Buffer.from('hello world')
 : new Buffer('hello world')

tape('passthrough', function(t) {
  t.plan(2)

  var pt = through()
  var dup = duplexify(pt, pt)

  dup.end('hello world')
  dup.on('finish', function() {
    t.ok(true, 'should finish')
  })
  dup.pipe(concat(function(data) {
    t.same(data.toString(), 'hello world', 'same in as out')
  }))
})

tape('passthrough + double end', function(t) {
  t.plan(2)

  var pt = through()
  var dup = duplexify(pt, pt)

  dup.end('hello world')
  dup.end()

  dup.on('finish', function() {
    t.ok(true, 'should finish')
  })
  dup.pipe(concat(function(data) {
    t.same(data.toString(), 'hello world', 'same in as out')
  }))
})

tape('async passthrough + end', function(t) {
  t.plan(2)

  var pt = through.obj({highWaterMark:1}, function(data, enc, cb) {
    setTimeout(function() {
      cb(null, data)
    }, 100)
  })

  var dup = duplexify(pt, pt)

  dup.write('hello ')
  dup.write('world')
  dup.end()

  dup.on('finish', function() {
    t.ok(true, 'should finish')
  })
  dup.pipe(concat(function(data) {
    t.same(data.toString(), 'hello world', 'same in as out')
  }))
})

tape('duplex', function(t) {
  var readExpected = ['read-a', 'read-b', 'read-c']
  var writeExpected = ['write-a', 'write-b', 'write-c']

  t.plan(readExpected.length+writeExpected.length+2)

  var readable = through.obj()
  var writable = through.obj(function(data, enc, cb) {
    t.same(data, writeExpected.shift(), 'onwrite should match')
    cb()
  })

  var dup = duplexify.obj(writable, readable)

  readExpected.slice().forEach(function(data) {
    readable.write(data)
  })
  readable.end()

  writeExpected.slice().forEach(function(data) {
    dup.write(data)
  })
  dup.end()

  dup.on('data', function(data) {
    t.same(data, readExpected.shift(), 'ondata should match')
  })
  dup.on('end', function() {
    t.ok(true, 'should end')
  })
  dup.on('finish', function() {
    t.ok(true, 'should finish')
  })
})

tape('async', function(t) {
  var dup = duplexify()
  var pt = through()

  dup.pipe(concat(function(data) {
    t.same(data.toString(), 'i was async', 'same in as out')
    t.end()
  }))

  dup.write('i')
  dup.write(' was ')
  dup.end('async')

  setTimeout(function() {
    dup.setWritable(pt)
    setTimeout(function() {
      dup.setReadable(pt)
    }, 50)
  }, 50)
})

tape('destroy', function(t) {
  t.plan(2)

  var write = through()
  var read = through()
  var dup = duplexify(write, read)

  write.destroy = function() {
    t.ok(true, 'write destroyed')
  }

  dup.on('close', function() {
    t.ok(true, 'close emitted')
  })

  dup.destroy()
  dup.destroy() // should only work once
})

tape('destroy both', function(t) {
  t.plan(3)

  var write = through()
  var read = through()
  var dup = duplexify(write, read)

  write.destroy = function() {
    t.ok(true, 'write destroyed')
  }

  read.destroy = function() {
    t.ok(true, 'read destroyed')
  }

  dup.on('close', function() {
    t.ok(true, 'close emitted')
  })

  dup.destroy()
  dup.destroy() // should only work once
})

tape('bubble read errors', function(t) {
  t.plan(2)

  var write = through()
  var read = through()
  var dup = duplexify(write, read)

  dup.on('error', function(err) {
    t.same(err.message, 'read-error', 'received read error')
  })
  dup.on('close', function() {
    t.ok(true, 'close emitted')
  })

  read.emit('error', new Error('read-error'))
  write.emit('error', new Error('write-error')) // only emit first error
})

tape('bubble write errors', function(t) {
  t.plan(2)

  var write = through()
  var read = through()
  var dup = duplexify(write, read)

  dup.on('error', function(err) {
    t.same(err.message, 'write-error', 'received write error')
  })
  dup.on('close', function() {
    t.ok(true, 'close emitted')
  })

  write.emit('error', new Error('write-error'))
  read.emit('error', new Error('read-error')) // only emit first error
})

tape('reset writable / readable', function(t) {
  t.plan(3)

  var toUpperCase = function(data, enc, cb) {
    cb(null, data.toString().toUpperCase())
  }

  var passthrough = through()
  var upper = through(toUpperCase)
  var dup = duplexify(passthrough, passthrough)

  dup.once('data', function(data) {
    t.same(data.toString(), 'hello')
    dup.setWritable(upper)
    dup.setReadable(upper)
    dup.once('data', function(data) {
      t.same(data.toString(), 'HELLO')
      dup.once('data', function(data) {
        t.same(data.toString(), 'HI')
        t.end()
      })
    })
    dup.write('hello')
    dup.write('hi')
  })
  dup.write('hello')
})

tape('cork', function(t) {
  var passthrough = through()
  var dup = duplexify(passthrough, passthrough)
  var ok = false

  dup.on('prefinish', function() {
    dup.cork()
    setTimeout(function() {
      ok = true
      dup.uncork()
    }, 100)
  })
  dup.on('finish', function() {
    t.ok(ok)
    t.end()
  })
  dup.end()
})

tape('prefinish not twice', function(t) {
  var passthrough = through()
  var dup = duplexify(passthrough, passthrough)
  var prefinished = false

  dup.on('prefinish', function() {
    t.ok(!prefinished, 'only prefinish once')
    prefinished = true
  })

  dup.on('finish', function() {
    t.end()
  })

  dup.end()
})

tape('close', function(t) {
  var passthrough = through()
  var dup = duplexify(passthrough, passthrough)

  passthrough.emit('close')
  dup.on('close', function() {
    t.ok(true, 'should forward close')
    t.end()
  })
})

tape('works with node native streams (net)', function(t) {
  t.plan(1)

  var server = net.createServer(function(socket) {
    var dup = duplexify(socket, socket)

    dup.once('data', function(chunk) {
      t.same(chunk, HELLO_WORLD)
      server.close()
      socket.end()
      t.end()
    })
  })

  server.listen(0, function () {
    var socket = net.connect(server.address().port)
    var dup = duplexify(socket, socket)

    dup.write(HELLO_WORLD)
  })
})
