var Config = require('../../src/lib/config')
var Transaction = require('../../src/instrumentation/transaction')
var Trace = require('../../src/instrumentation/trace')

var InstrumentationMock = function () {
  this._queue = []
}

InstrumentationMock.prototype.add = function (transaction) {
  this._queue.push(transaction)
}

InstrumentationMock.prototype.startTransaction = function (name, type, options) {
  return new Transaction(this, name, type, options)
}

describe('instrumentation.transaction', function () {
  var instrumentationMock
  var config = Config
  config.init()
  beforeEach(function () {
    instrumentationMock = new InstrumentationMock()
  })

  it('should adjust rootTrace to earliest trace', function (done) {
    var firstTrace = new Trace(this, 'first-trace-signature', 'first-trace', { config: config })
    firstTrace.end()

    var transaction = instrumentationMock.startTransaction('/', 'transaction', { config: config })
    transaction.end()

    firstTrace.transaction = transaction
    firstTrace.setParent(transaction._rootTrace)
    transaction.addEndedTraces([firstTrace])

    var lastTrace = transaction.startTrace('last-trace-signature', 'last-trace')
    lastTrace.end()

    setTimeout(function () {
      expect(transaction._rootTrace._start).toBe(firstTrace._start)
      expect(transaction._rootTrace._end).toBe(lastTrace._end)
      expect(transaction._rootTrace._diff).toBe(lastTrace._end - firstTrace._start)
      done()
    }, 10) // todo fix race condition
  })

  it('should adjust rootTrace to latest trace', function (done) {
    var transaction = instrumentationMock.startTransaction('/', 'transaction', { config: config })
    var rootTraceStart = transaction._rootTrace._start

    var firstTrace = transaction.startTrace('first-trace-signature', 'first-trace')
    firstTrace.end()

    var longTrace = transaction.startTrace('long-trace-signature', 'long-trace')

    var lastTrace = transaction.startTrace('last-trace-signature', 'last-trace')
    lastTrace.end()

    transaction.end()

    setTimeout(function () {
      longTrace.end()

      setTimeout(function () {
        expect(transaction._rootTrace._start).toBe(rootTraceStart)
        expect(transaction._rootTrace._end).toBe(longTrace._end)
        expect(transaction._rootTrace._diff).toBe(longTrace._end - rootTraceStart)
        done()
      })
    }, 500)
  })

  xit('should not start any traces after transaction has been added to queue', function (done) {
    var transaction = instrumentationMock.startTransaction('/', 'transaction', { config: config })
    transaction.end()
    var firstTrace = transaction.startTrace('first-trace-signature', 'first-trace')
    firstTrace.end()
    setTimeout(function () {
      // todo: transaction has already been added to the queue, shouldn't accept more traces

      var lastTrace = transaction.startTrace('last-trace-signature', 'last-trace')
      fail('done transaction should not accept more traces, now we simply ignore the newly stared trace.')
      lastTrace.end()
    })
  })
})

@@ -655,24 +655,689 @@
 ock()%0A  %7D)%0A%0A
+  xit('should contain correct number of traces in the end', function (done) %7B%0A    var firstTrace = new Trace(this, 'first-trace-signature', 'first-trace', %7B config: config %7D)%0A    firstTrace.end()%0A%0A    var transaction = instrumentationMock.startTransaction('/', 'transaction', %7B config: config %7D)%0A    transaction.end()%0A%0A    firstTrace.transaction = transaction%0A    firstTrace.setParent(transaction._rootTrace)%0A    transaction.addEndedTraces(%5BfirstTrace%5D)%0A%0A    var lastTrace = transaction.startTrace('last-trace-signature', 'last-trace')%0A    lastTrace.end()%0A%0A    setTimeout(function () %7B%0A      expect(transaction.traces.length).toBe(3)%0A      done()%0A    %7D, 100)%0A  %7D)%0A%0A
   it('should
@@ -2137,16 +2137,17 @@
    %7D, 10
+0
 ) // tod

add test to transaction.spec.js