Source: commands/macro.js

var Command = require('./command');
/**
 * @class Macro
 * @augments Command
 * @classdesc This extended Command-class is the build-in macro-command. It's implementation 
 * of the execute() method, is a mechanism to synchronously run subcommands and return their
 * individual results as an array of CommandResults, wrapped inside a promise.   
 * It totally depends on the user configuration file, which can be specified in the module's 'config.json'.
 * The user configuration must have a key called 'cmdSequence', in which a chain of commands
 * is specified as an array. Since those commands are assumed to depend on each other, they
 * will be executed in order from left to right (start with index 0 and increment with 1).<br>
 * Also checkout: {@link https://github.com/ruckola/mcdemo Example project}<br><br>
 * <em>IMPORTANT NOTE!: </em><i>Each command that extends the abstract Command-class must return a promise.
 * Since each command has a build in CommandResult object, you can use this to store your data,
 * and pass it around.</i> 
 * @author ruckola
 */
class Macro extends Command {

    execute(context) {
        var self = this;
        return new Promise(function (resolve, reject) {
            var Helper = require('../core/helper');

            if (context.parameters.userConfiguration) {
                var pMacroCfg = Helper.getMacroConfiguration(
                    context.parameters.userConfiguration,
                    context.parameters.macroID);

                Promise.all([pMacroCfg]).then((values) => {

                    context.parameters.macroConfiguration = values[0];
                    var cfg = context.parameters.macroConfiguration;
                    var seq = cfg.cmdSequence;
                    var ctxt = context;

                    seq.reduce((prevCmd, curCmd) => {

                        return prevCmd.then((resultObj) => {

                            if (resultObj)
                                self.result.data.push(resultObj);

                            //make sure to get the namespace right
                            //if namespace parameter in config available
                            //then use it.
                            //else resolve individual command names.
                            //In this situation, you can use different namespaces
                            //by using prefixes in the commandsequence.     
                            var cd = context.parameters.userCommandsRootDir; //commanddir
                            if (context.parameters.macroConfiguration.namespace) {
                                var path = require('path');
                                var cd = path.join(context.parameters.userCommandsRootDir,
                                    context.parameters.macroConfiguration.namespace)
                            }

                            var cmd = CommandFactory.getCommand(curCmd, cd);
                            
                            ctxt.parameters.cmdConfiguration = cfg[curCmd];
                            ctxt.parameters.action = curCmd;
                            // make the results of previous subcommands available via the commandContext.
                            ctxt.parameters.prevResults = self.result.data;

                            return cmd.execute(ctxt);
                        });
                    }, Promise.resolve()).then(
                        (resultObj) => {

                            //set the result of the macro command itself.
                            self.result.cmd = self.constructor.name;
                            self.result.data.push(resultObj);
                            self.result.msg = "The macro has finished successfully!";
                            resolve(self.result);
                        },
                        (e) => console.log(e)
                        );
                });

            }
        })
    }
}

module.exports = Macro;