// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

'use strict'

const childProcess = require('child_process')

/**
 * Options for configuring an executed command.
 *
 * @record
 */
class Options {
  constructor() {
    /**
     * Command line arguments for the child process, if any.
     * @type (!Array<string>|undefined)
     */
    this.args

    /**
     * Environment variables for the spawned process. If unspecified, the
     * child will inherit this process' environment.
     *
     * @type {(!Object<string, string>|undefined)}
     */
    this.env

    /**
     * IO conifguration for the spawned server child process. If unspecified,
     * the child process' IO output will be ignored.
     *
     * @type {(string|!Array<string|number|!stream.Stream|null|undefined>|
     *           undefined)}
     * @see <https://nodejs.org/dist/latest-v8.x/docs/api/child_process.html#child_process_options_stdio>
     */
    this.stdio
  }
}

/**
 * Describes a command's termination conditions.
 */
class Result {
  /**
   * @param {?number} code The exit code, or {@code null} if the command did not
   *     exit normally.
   * @param {?string} signal The signal used to kill the command, or
   *     {@code null}.
   */
  constructor(code, signal) {
    /** @type {?number} */
    this.code = code

    /** @type {?string} */
    this.signal = signal
  }

  /** @override */
  toString() {
    return `Result(code=${this.code}, signal=${this.signal})`
  }
}

const COMMAND_RESULT =
  /** !WeakMap<!Command, !Promise<!Result>> */ new WeakMap()
const KILL_HOOK = /** !WeakMap<!Command, function(string)> */ new WeakMap()

/**
 * Represents a command running in a sub-process.
 */
class Command {
  /**
   * @param {!Promise<!Result>} result The command result.
   * @param {function(string)} onKill The function to call when {@link #kill()}
   *     is called.
   */
  constructor(result, onKill) {
    COMMAND_RESULT.set(this, result)
    KILL_HOOK.set(this, onKill)
  }

  /**
   * @return {!Promise<!Result>} A promise for the result of this
   *     command.
   */
  result() {
    return /** @type {!Promise<!Result>} */ (COMMAND_RESULT.get(this))
  }

  /**
   * Sends a signal to the underlying process.
   * @param {string=} opt_signal The signal to send; defaults to `SIGTERM`.
   */
  kill(opt_signal) {
    KILL_HOOK.get(this)(opt_signal || 'SIGTERM')
  }
}

// PUBLIC API

/**
 * Spawns a child process. The returned {@link Command} may be used to wait
 * for the process result or to send signals to the process.
 *
 * @param {string} command The executable to spawn.
 * @param {Options=} opt_options The command options.
 * @return {!Command} The launched command.
 */
function exec(command, opt_options) {
  const options = opt_options || {}

  let proc = childProcess.spawn(command, options.args || [], {
    env: options.env || process.env,
    stdio: options.stdio || 'ignore',
  })

  // This process should not wait on the spawned child, however, we do
  // want to ensure the child is killed when this process exits.
  proc.unref()
  process.once('exit', onProcessExit)

  const result = new Promise((resolve, reject) => {
    proc.once('exit', (code, signal) => {
      proc = null
      process.removeListener('exit', onProcessExit)
      resolve(new Result(code, signal))
    })

    proc.once('error', (err) => {
      reject(err)
    })
  })
  return new Command(result, killCommand)

  function onProcessExit() {
    killCommand('SIGTERM')
  }

  function killCommand(signal) {
    process.removeListener('exit', onProcessExit)
    if (proc) {
      proc.kill(signal)
      proc = null
    }
  }
}

// Exported to improve generated API documentation.

module.exports = {
  Command,
  Options,
  Result,
  exec,
}
