var crypto = require('crypto')
var pull = require('pull-stream')
var R = new Buffer(crypto.randomBytes(16).toString('hex'), 'ascii')
var pair = require('pull-pair')
var assert = require('assert')
var tape = require('tape')

var handshake = require('../')

function agreement (timeout, cb) {
  if(!cb) cb = timeout, timeout = null

  var stream = handshake({timeout: timeout || 100}, cb)
  var shake = stream.handshake
  shake.write(R)
  shake.read(32, function (err, data) {
    if(err) cb(err)
    else {
      assert.deepEqual(data, R)
      cb(null, shake.rest())
    }
  })

  return stream
}

tape('simple', function (t) {

  var hello = new Buffer('hello there did it work?', 'ascii')

  var client = agreement(function (err, stream) {
    pull(
      pull.values([hello, hello, hello]),
      stream,
      pull.collect(function (err, data) {
        t.deepEqual(
          Buffer.concat(data),
          Buffer.concat([hello, hello, hello])
        )
        console.log('done')
        t.end()
      })
    )
  })

  var server = agreement(function (err, stream) {
    pull(stream, stream) //ECHO
  })

  function logger (name) {
    return pull.through(function (data) {
      console.log(name, data.toString('utf8'))
    })
  }

  pull(client, logger('A->B'), server, logger('A<-B'), client)

})


function abort (cb) {
  var stream = handshake({timeout: 100}, cb)
  var shake = stream.handshake
  shake.read(16, function (err, data) {
    shake.abort(new Error('intentional'))
  })

  return stream
}


tape('abort', function (t) {

  var client = agreement(function (err, stream) {

  })

  var server = abort(function (err) {
    t.ok(err)
    t.end()
  })

  pull(client, server, client)

})

function hang () {
  var _cb
  return function (abort, cb) {
    if(abort) {
      if(_cb) _cb(abort)
      cb(abort)
    }
    else
      _cb = cb

  }
}

tape('timeout', function (t) {
  var timeout = false
  var client = agreement(200, function (err, stream) {
    t.ok(timeout)
    console.log(err)
    t.ok(err)
    t.end()
  })

  setTimeout(function () {
    timeout = true
  }, 100)

  pull(
    hang(),
    client
  )

})

tape('timeout does not apply to the rest of the stream', function (t) {
  var reader = handshake({timeout: 100})
  var once = false
  pull(
    function (abort, cb) {
      if(once)
        setTimeout(function () {
          once = true
          cb(null, new Buffer('hello world'))
        }, 200)
      else
        cb(true)
    },
    reader
  )

  pull(
    reader.handshake.rest(),
    pull.collect(function (err, ary) {
      console.log(err)
      t.notOk(err)
      t.deepEqual(ary, [])
      t.end()
    })
  )
})


@@ -215,16 +215,48 @@
 ('tape')
+%0Avar Hang = require('pull-hang')
 %0A%0Avar ha
@@ -1737,164 +1737,8 @@
 %7D)%0A%0A
-function hang () %7B%0A  var _cb%0A  return function (abort, cb) %7B%0A    if(abort) %7B%0A      if(_cb) _cb(abort)%0A      cb(abort)%0A    %7D%0A    else%0A      _cb = cb%0A%0A  %7D%0A%7D%0A%0A
 tape
@@ -1981,17 +1981,17 @@
 ll(%0A    
-h
+H
 ang(),%0A 
@@ -2529,12 +2529,13 @@
  %7D)%0A  )%0A%7D)%0A%0A
+%0A

test timeouts