/*
    Module to sanitize args to be sent to analytics, removing
    private user info.
// command hierarchy
    * indicates arg values are stripped and only count, and list of used flags is returned
phonegap
    [help, create*, push*, build, prepare, compile, info, serve*, app*, install, run]
    remote
        [login*, logout, build, install, run]
    plugin
        [ls, list, rm, remove, add*]
    plugins
        [ls, list, rm, remove, add*]
    platform
        [ls, list, rm, remove, add*]
    platforms
        [ls, list, rm, remove, add*]
    template
        [list, search]
    cordova
        [create*, serve*]
        plugin
            [ls, list, rm, remove, add*]
        plugins
            [ls, list, rm, remove, add*]
        platform
            [ls, list, rm, remove, add*]
        platforms
            [ls, list, rm, remove, add*]
*/

// returns an array of args that are switches ex. --target, -d, --verbose, --secret=forbidden
function getSwitches (args) {
    return args.filter(function (arg) { // only switch elems
        return arg && arg.indexOf('-') === 0 && arg !== '-v';
    }).map(function (elem) { // remove anything after an '='
        return elem.split('=')[0];
    });
}

// helper, returns the first index into arr1 of the items in arr2
function indexOfAny (arr1, arr2) {
    var index = -1;
    arr2.some(function (elem, pos) {
        if (arr1.indexOf(elem) > -1) {
            index = pos;
            return true;
        }
    });
    return index;
}

// returns an array of args that are NOT switches
// optional parameter that controls filtering out `-v` or `--version`, as that is treated
// as a top-level command in pg-cli, so useful to treat it uniquely. default to filter out.
function filterSwitches (args, filterVersion) {
    filterVersion = (typeof filterVersion !== 'undefined' ? filterVersion : true);
    return args.filter(function (arg) {
        return arg && (filterVersion ? !(arg.indexOf('-') === 0) : (arg === '-v' || arg === '--version' || !(arg.indexOf('-') === 0)));
    });
}

// Returns an array of filtered parameters that we can log to analytics
// Removes certain tokens, such as particular plugins being added/removed, for privacy reasons
function filterParameters (args) {
    var params = [];
    if (args.length === 0) return params;
    if (indexOfAny(args, ['help', '--help', '-h']) > -1) {
        params = args.slice(1);
    } else {
        var cmd = args[0].toLowerCase();
        switch (cmd) {
        case 'template' : // these choices log ALL args
        case 'build' :
        case 'prepare' :
        case 'compile' :
        case 'emulate' :
        case 'install' :
        case 'version' :
        case '-v' :
        case 'info' :
        case 'run' :
            // add 'em all if they exist
            if (args.length > 1) {
                params = args.slice(1);
            }
            break;
        case 'serve' : // for these commands, we do not want to log anything beyond just the command
        case 'app' :
        case 'create' :
        case 'push' :
            break;
        case 'cordova' : // log `cordova + command`
        case 'local' : // log `local + command`
            // these commands need recursive parsing of parameters - invoke one more time
            params = filterParameters(args.slice(1)); // recurse
            break;
        case 'platforms': // this is an alias, just fall thru
        case 'platform' :
        case 'plugins': // alias fall thru
        case 'plugin' :
            // For the list commands, log all arguments.
            if (indexOfAny(args, ['list', 'ls']) > -1) {
                params = args.slice(1);
            } else {
                // for the add+rm command, we dont log _which_ plugins/platforms are
                // being added/removed.
                // TODO: perhaps we should log core plugins?
                params = [args[1]];
                if (['platform', 'platforms'].indexOf(cmd) > -1) {
                    // For platforms add/rm, for certain specific platforms, we log
                    // which platform is being managed.
                    // TODO: only pull out local dir platforms
                    // cordova-platform-id should be fine
                    // git urls (may) be fine ??
                    // ios, android, windows, wp8, ...
                    if (args[2] && ['android', 'ios', 'wp8', 'windows'].indexOf(args[2]) > -1) {
                        params.push(args[2]);
                    }
                }
            }
            break;
        case 'remote' :
            // login needs special treatment
            if (args.length > 2 && args[1].toLowerCase() === 'login') {
                params = ['login'];
            } else { // logout, build, install, run <platform>
                params = args.slice(1);
            }
            break;
        }
    }
    return filterSwitches(params);
}

// Returns a string representing the command the user ran.
// May return a compound command in the case of "cordova" or "local" commands
function getCommand (args) {
    // for the filterVersion parameter below, for the purposes of retrieving
    // the top-level command invoked, we treat the -v / --version flag as a
    // top-level command, so, lets not filter out version switches in this case.
    args = filterSwitches(args, false/* filterVersion */);
    var cmd = args[0] || 'help'; // if no command is passed, assume it is help
    if (cmd.toLowerCase() === 'cordova' || cmd.toLowerCase() === 'local') {
        cmd += ':' + args[1];
    }
    return cmd;
}

module.exports = {
    getSwitches: getSwitches,
    filterParameters: filterParameters,
    getCommand: getCommand,
    // this function takes an args array which is expect to start with the command
    // so if we call `phonegap serve --port 1337` this method would receive `serve --port 1337`
    // ideally we only want to log `serve --port`
    // returns an object with "command" and "params" string properties
    stringifyForGoogleAnalytics: function (args) {
        args = args || [];
        var argsToLog = {'command': '-', 'params': '-', 'count': 0};

        if (args.length > 0) {
            argsToLog.command = getCommand(args);
            argsToLog.count = args.length;
            var filteredParams = filterParameters(args);
            argsToLog.params = filteredParams.join() || '-';
            if (['platform', 'platforms'].indexOf(args[0].toLowerCase()) > -1) {
                var subCommand = filteredParams[0] ? filteredParams[0] : '-';
                if (['add', 'rm', 'remove'].indexOf(subCommand) > -1) {
                    var platform = filteredParams[1];
                    // todo: only pull out local dir platforms
                    // cordova-platform-id should be fine
                    // git urls (may) be fine ??
                    // ios, android, windows, wp8, ...
                    if (platform && ['android', 'ios', 'wp8', 'windows'].indexOf(platform) > -1) {
                        subCommand += ':' + platform;
                    }
                    argsToLog.params = subCommand;
                }
            }
            // Tack on switches at the end, or if there are no parameters, replace with just switches
            var switches = getSwitches(args);
            if (switches.length) {
                if (argsToLog.params === '-') {
                    argsToLog.params = '' + switches;
                } else {
                    argsToLog.params += ' ' + switches;
                }
            }
        }
        return argsToLog;
    }
};
