const { exec } = require('child_process');
const EXEC_OPTIONS = { maxBuffer: 1024*10000 };

function cmd(x, options = {}) {
    if (!x) {
        return Promise.resolve();
    }

    if (x instanceof Promise) {
        return x;
    }

    if (typeof x === 'function') {
        return Promise.resolve(x());
    }

    if (x instanceof Array) {
        return x.reduce((chain, item) => chain.then(() => cmd(item)), Promise.resolve());
    }

    console.log(`* ${x}`);

    let { verbose } = options;

    return new Promise((resolve, reject) => {
        const cliProcess = exec(x, EXEC_OPTIONS, (err, stdout, stderr) => {
            if (err) {
                console.log(`✘ ${x}`);
                return reject(err);
            }

            resolve(stdout.toString());
        });

        if (verbose) {
            cliProcess.stdout.pipe(process.stdout);
        }
    })
        .catch(e => {
            if (verbose) {
                console.log(e);
            }

            throw e;
        });
};

module.exports = cmd;
