'use strict'
const Base = require('./base.js')

const assert = require('assert')
const util = require('util')
const ownOr = require('own-or')
const path = require('path')
const cleanYamlObject = require('./clean-yaml-object.js')
const cp = require('child_process')

class Spawn extends Base {
  constructor (options) {
    options = options || {}
    super(options)

    this.command = options.command

    if (!this.command)
      throw new TypeError('no command provided')

    this.args = options.args
    // stdout must be a pipe
    if (options.stdio) {
      if (typeof options.stdio === 'string')
        this.stdio = [ options.stdio, 'pipe', options.stdio ]
      else
        this.stdio = options.stdio.slice(0)
    } else
      this.stdio = [ 0, 'pipe', 2 ]

    this.stdio[1] = 'pipe'
    options.stdio = this.stdio
    const env = options.env || process.env
    this.env = Object.assign({}, env)

    this.env.TAP = '1'
    if (this.bail)
      this.env.TAP_BAIL = '1'

    this.cwd = ownOr(options, 'cwd', process.cwd())
    options.cwd = this.cwd
    if (!this.name) {
      if (this.command === process.execPath) {
        this.name = path.basename(process.execPath) + ' ' +
          this.args.map(a =>
            a.indexOf(this.cwd) === 0 ?
              './' + a.substr(this.cwd.length + 1).replace(/\\/g, '/')
            : a).join(' ')
      } else {
        this.name = this.command + ' ' + this.args.join(' ')
      }
    }

    this.proc = null
  }

  endAll () {
    if (this.proc)
      this.proc.kill('SIGKILL')
    this.parser.abort('test unfinished')
    this.callCb()
  }

  main (cb) {
    this.cb = cb
    this.setTimeout(this.options.timeout)
    const options = Object.assign({
      cwd: this.cwd,
      env: this.env,
      stdio: this.stdio
    }, this.options)
    try {
      const proc = this.proc = cp.spawn(this.command, this.args, options)
      proc.stdout.pipe(this.parser)
      proc.on('close', (code, signal) => this.onprocclose(code, signal))
      proc.on('error', er => this.threw(er))
      this.emit('process', proc)
      if (this.parent)
        this.parent.emit('spawn', this)
    } catch (er) {
      this.threw(er)
    }
  }

  callCb () {
    if (this.cb)
      this.cb()
    this.cb = null
  }

  threw (er, extra, proxy) {
    extra = Base.prototype.threw.call(this, er, extra, proxy)
    extra = cleanYamlObject(extra)
    // unhook entirely
    this.parser.abort(er.message, extra)
    if (this.proc) {
      this.proc.stdout.removeAllListeners('data')
      this.proc.stdout.removeAllListeners('end')
      this.proc.removeAllListeners('close')
      this.proc.kill('SIGKILL')
    }
    this.callCb()
  }

  onprocclose (code, signal) {
    this.debug('SPAWN close %j %s', code, signal)
    this.options.exitCode = code
    if (signal)
      this.options.signal = signal

    // spawn closing with no tests is treated as a skip.
    if (this.results.plan && this.results.plan.skipAll && !code && !signal)
      this.options.skip = this.results.plan.skipReason || true

    if (code || signal) {
      this.results.ok = false
      this.parser.ok = false
    }
    return this.callCb()
  }

  timeout (extra) {
    if (this.proc) {
      this.proc.kill('SIGTERM')
      const t = setTimeout(() => {
        if (!this.options.signal && this.options.exitCode === undefined) {
          Base.prototype.timeout.call(this, extra)
          this.proc.kill('SIGKILL')
        }
      }, 1000)
      /* istanbul ignore else */
      if (t.unref)
        t.unref()
    }
  }
}

module.exports = Spawn
