/**
 * Utility for running programs from the command line.
 */

import colors from "colors";
import { exec } from "child_process";

colors.setTheme({
  debug: "cyan",
  error: "red",
  prompt: "grey",
});

export function commandRunner(program) {
  return (cmd, options = { showOutput: false }) => {
    if (process.env.DEBUG) {
      console.log(
        colors.debug(`Pretending to run: ${program} ${colors.prompt(cmd)}`)
      );
      return Promise.resolve("");
    }
    return toExecPromise(`${program} ${cmd}`, { ...options, timeout: 200000 });
  };
}

function toExecPromise(cmd, { timeout, showOutput }) {
  return new Promise((resolve, reject) => {
    const id = setTimeout(() => {
      reject(new Error(`Command took too long: ${cmd}`));
      proc.kill("SIGTERM");
    }, timeout);
    const proc = exec(cmd, (err, stdout) => {
      clearTimeout(id);
      if (err) {
        return reject(err);
      }
      resolve(stdout);
    });
    if (showOutput) {
      proc.stderr.pipe(process.stderr);
      proc.stdout.pipe(process.stdout);
    }
    proc.on("close", number => {
      if (number === 1) {
        process.exit(1);
      }
    });
  });
}
