/**
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF 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.
*/

var child_process = require('child_process');
var fs = require('fs-extra');
var path = require('path');
var _ = require('underscore');
var Q = require('q');
var which = require('which');
var events = require('./events');
var iswin32 = process.platform === 'win32';

// On Windows, spawn() for batch files requires absolute path & having the extension.
function resolveWindowsExe (cmd) {
    var winExtensions = ['.exe', '.bat', '.cmd', '.js', '.vbs'];
    function isValidExe (c) {
        return winExtensions.includes(path.extname(c)) && fs.existsSync(c);
    }
    if (isValidExe(cmd)) {
        return cmd;
    }
    cmd = which.sync(cmd, { nothrow: true }) || cmd;
    if (!isValidExe(cmd)) {
        winExtensions.some(function (ext) {
            if (fs.existsSync(cmd + ext)) {
                cmd = cmd + ext;
                return true;
            }
        });
    }
    return cmd;
}

function maybeQuote (a) {
    if (/^[^"].*[ &].*[^"]/.test(a)) return '"' + a + '"';
    return a;
}

/**
 * A special implementation for child_process.spawn that handles
 *   Windows-specific issues with batch files and spaces in paths. Returns a
 *   promise that succeeds only for return code 0. It is also possible to
 *   subscribe on spawned process' stdout and stderr streams using progress
 *   handler for resultant promise.
 *
 * @example spawn('mycommand', [], {stdio: 'pipe'}) .progress(function (stdio){
 *   if (stdio.stderr) { console.error(stdio.stderr); } })
 *   .then(function(result){ // do other stuff })
 *
 * @param   {String}   cmd       A command to spawn
 * @param   {String[]} [args=[]]  An array of arguments, passed to spawned
 *   process
 * @param   {Object}   [opts={}]  A configuration object
 * @param   {String|String[]|Object} opts.stdio Property that configures how
 *   spawned process' stdio will behave. Has the same meaning and possible
 *   values as 'stdio' options for child_process.spawn method
 *   (https://nodejs.org/api/child_process.html#child_process_options_stdio).
 * @param {Object}     [env={}]  A map of extra environment variables
 * @param {String}     [cwd=process.cwd()]  Working directory for the command
 * @param {Boolean}    [chmod=false]  If truthy, will attempt to set the execute
 *   bit before executing on non-Windows platforms
 *
 * @return  {Promise}        A promise that is either fulfilled if the spawned
 *   process is exited with zero error code or rejected otherwise. If the
 *   'stdio' option set to 'default' or 'pipe', the promise also emits progress
 *   messages with the following contents:
 *   {
 *       'stdout': ...,
 *       'stderr': ...
 *   }
 */
exports.spawn = function (cmd, args, opts) {
    args = args || [];
    opts = opts || {};
    var spawnOpts = {};
    var d = Q.defer();

    if (iswin32) {
        cmd = resolveWindowsExe(cmd);
        // If we couldn't find the file, likely we'll end up failing,
        // but for things like "del", cmd will do the trick.
        if (path.extname(cmd) !== '.exe') {
            var cmdArgs = '"' + [cmd].concat(args).map(maybeQuote).join(' ') + '"';
            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
            args = [['/s', '/c', cmdArgs].join(' ')];
            cmd = 'cmd';
            spawnOpts.windowsVerbatimArguments = true;
        } else if (!fs.existsSync(cmd)) {
            // We need to use /s to ensure that spaces are parsed properly with cmd spawned content
            args = ['/s', '/c', cmd].concat(args).map(maybeQuote);
        }
    }

    if (opts.stdio !== 'default') {
        // Ignore 'default' value for stdio because it corresponds to child_process's default 'pipe' option
        spawnOpts.stdio = opts.stdio;
    }

    if (opts.cwd) {
        spawnOpts.cwd = opts.cwd;
    }

    if (opts.env) {
        spawnOpts.env = _.extend(_.extend({}, process.env), opts.env);
    }

    if (opts.chmod && !iswin32) {
        try {
            // This fails when module is installed in a system directory (e.g. via sudo npm install)
            fs.chmodSync(cmd, '755');
        } catch (e) {
            // If the perms weren't set right, then this will come as an error upon execution.
        }
    }

    events.emit(opts.printCommand ? 'log' : 'verbose', 'Running command: ' + maybeQuote(cmd) + ' ' + args.map(maybeQuote).join(' '));

    var child = child_process.spawn(cmd, args, spawnOpts);
    var capturedOut = '';
    var capturedErr = '';

    if (child.stdout) {
        child.stdout.setEncoding('utf8');
        child.stdout.on('data', function (data) {
            capturedOut += data;
            d.notify({'stdout': data});
        });
    }

    if (child.stderr) {
        child.stderr.setEncoding('utf8');
        child.stderr.on('data', function (data) {
            capturedErr += data;
            d.notify({'stderr': data});
        });
    }

    child.on('close', whenDone);
    child.on('error', whenDone);
    function whenDone (arg) {
        child.removeListener('close', whenDone);
        child.removeListener('error', whenDone);
        var code = typeof arg === 'number' ? arg : arg && arg.code;

        events.emit('verbose', 'Command finished with error code ' + code + ': ' + cmd + ' ' + args);
        if (code === 0) {
            d.resolve(capturedOut.trim());
        } else {
            var errMsg = cmd + ': Command failed with exit code ' + code;
            if (capturedErr) {
                errMsg += ' Error output:\n' + capturedErr.trim();
            }
            var err = new Error(errMsg);
            if (capturedErr) {
                err.stderr = capturedErr;
            }
            if (capturedOut) {
                err.stdout = capturedOut;
            }
            err.code = code;
            d.reject(err);
        }
    }

    return d.promise;
};

exports.maybeSpawn = function (cmd, args, opts) {
    if (fs.existsSync(cmd)) {
        return exports.spawn(cmd, args, opts);
    }
    return Q(null);
};
