'use strict'
const Test = require('./test.js')
const Stdin = require('./stdin.js')
const Spawn = require('./spawn.js')
const util = require('util')
const objToYaml = require('./obj-to-yaml.js')
const yaml = require('js-yaml')
const _didPipe = Symbol('_didPipe')

const monkeypatchEpipe = () => {
  const emit = process.stdout.emit
  process.stdout.emit = (ev, er) => {
    if (ev !== 'error' || er.code !== 'EPIPE')
      return emit.apply(process, arguments)
  }
}

const monkeypatchExit = () => {
  const exit = process.exit
  const reallyExit = process.reallyExit

  // ensure that we always get run, even if a user does
  // process.on('exit', process.exit)
  process.reallyExit = code =>
    reallyExit.call(process, onExitEvent(code))

  process.exit = code =>
    exit.call(process, onExitEvent(code))

  process.on('exit', onExitEvent)
}

class TAP extends Test {
  constructor (options) {
    super(options)
    this.runOnly = process.env.TAP_ONLY === '1'
    this.start = Date.now()
    this[_didPipe] = false
  }

  pipe () {
    this[_didPipe] = true
    this.setTimeout(this.options.timeout)
    this.pipe = Test.prototype.pipe
    this.write = Test.prototype.write
    const ret = this.pipe.apply(this, arguments)
    this.process()
    return ret
  }

  write (c, e) {
    // this resets write and pipe to standard values
    this.pipe(process.stdout)
    this.patchProcess()
    return super.write(c, e)
  }

  patchProcess () {
    monkeypatchEpipe()
    monkeypatchExit()
    process.on('uncaughtException', this.threw)
    process.on('unhandledRejection', er => this.threw(er))
  }

  onbail () {
    Test.prototype.onbail.apply(this, arguments)
    this.endAll()
    process.exit(1)
  }

  onbeforeend () {
    if (this[_didPipe] && this.time && !this.bailedOut)
      this.emit('data', '# time=' + this.time + 'ms\n')
  }

  ondone () {
    try {
      this.emit('teardown')
    } catch (er) {
      this.threw(er)
    }
  }

  // Root test runner doesn't have the 'teardown' event, because it
  // isn't hooked into any parent Test as a harness.
  teardown (fn) {
    this.autoend()
    return Test.prototype.teardown.apply(this, arguments)
  }
  tearDown (fn) {
    return this.teardown(fn)
  }
}

let didOnExitEvent = false
const onExitEvent = code => {
  if (didOnExitEvent)
    return process.exitCode || code

  didOnExitEvent = true

  if (!tap.results)
    tap.endAll()

  if (tap.results && !tap.results.ok && code === 0) {
    process.exitCode = 1
    if (process.version.match(/^v0\.(10|[0-9])\./))
      process.exit(code)
  }

  return process.exitCode || code || 0
}


const opt = { name: 'TAP' }
if (process.env.TAP_DEBUG === '1' ||
    /\btap\b/.test(process.env.NODE_DEBUG || ''))
  opt.debug = true

if (process.env.TAP_GREP) {
  opt.grep = process.env.TAP_GREP.split('\n').map(g => {
    const p = g.match(/^\/(.*)\/([a-z]*)$/)
    g = p ? p[1] : g
    const flags = p ? p[2] : ''
    return new RegExp(g, flags)
  })
}

if (process.env.TAP_GREP_INVERT === '1')
  opt.grepInvert = true

if (process.env.TAP_ONLY === '1')
  opt.only = true

const tap = new TAP(opt)
module.exports = tap
tap.mocha = require('./mocha.js')
tap.mochaGlobals = tap.mocha.global

tap.Test = Test
tap.Spawn = Spawn
tap.Stdin = Stdin
tap.synonyms = require('./synonyms.js')

// SIGTERM means being forcibly killed, almost always by timeout
const onExit = require('signal-exit')
let didTimeoutKill = false
onExit((code, signal) => {
  if (signal !== 'SIGTERM' || !tap[_didPipe] || didTimeoutKill)
    return

  const handles = process._getActiveHandles().filter(h =>
    h !== process.stdout &&
    h !== process.stdin &&
    h !== process.stderr
  )
  const requests = process._getActiveRequests()

  // Ignore this because it's really hard to test cover in a way
  // that isn't inconsistent and unpredictable.
  /* istanbul ignore next */
  const extra = {
    at: null,
    signal: signal
  }
  if (requests.length) {
    extra.requests = requests.map(r => {
      const ret = {}
      ret.type = r.constructor.name

      // most everything in node has a context these days
      /* istanbul ignore else */
      if (r.context)
        ret.context = r.context

      return ret
    })
  }
  if (handles.length) {
    extra.handles = handles.map(h => {
      const ret = {}
      ret.type = h.constructor.name

      // all of this is very internal-ish
      /* istanbul ignore next */
      if (h.msecs)
        ret.msecs = h.msecs

      /* istanbul ignore next */
      if (h._events)
        ret.events = Object.keys(h._events)

      /* istanbul ignore next */
      if (h._sockname)
        ret.sockname = h._sockname

      /* istanbul ignore next */
      if (h._connectionKey)
        ret.connectionKey = h._connectionKey

      return ret
    })
  }

  // this is impossible to cover, because it happens after nyc has
  // already done its stuff.
  /* istanbul ignore else */
  if (!tap.results && tap.timeout)
    tap.timeout(extra)
  else {
    console.error('possible timeout: SIGTERM received after tap end')
    if (extra.handles || extra.requests) {
      delete extra.signal
      if (!extra.at) {
        delete extra.at
      }
      const yaml = require('js-yaml')
      console.error(objToYaml(extra))
    }
    didTimeoutKill = true
    process.kill(process.pid, 'SIGTERM')
  }
})
