Source: core/controller.js

CommandFactory = require("./commandFactory");
/**
 * @class Controller
 * @author ruckola
 * @classdesc The controller does multiple things in two phases:
 * <pre>
 *  When instantiated:
 *      1) It creates a new commandContext.
 *           (So the kickstarter can change or add parameters to the context.)
 *  
 *  When processing: 
 *      2) It delegates the resolving of the action parameter to a real Command object,
 *         to the commandFactory.
 *      4) It passes the commandContext as a parameter value into the command.
 *      5) It executes the command.
 *      6) It returns the result to the kickstarter.
 * </pre> 
 * When in 'single command mode', the controller will also search for an optional config file in config dir.<br>
 * This filename must be equal to the command-name, except for the extension. (myCmd.js --> myCmd.json)<br>
 * Any subdirectories are ommitted.
 * For macro's the configuration is loaded by the build-in {@link Macro} command.<br>
 * The loading for single commands is synchronous and blocking, so it can be done here.
 * For macro's it happens to be async and therefore a different strategy is needed. 
 * @property {CommandContext} this.context - A new instance of the CommandContext class.
 */
class Controller {

    /**
    * @constructor
    * @description Creates a new instance of the CommandContext class.
    */
    constructor() {
        var CommandContext = require("./commandContext");
        this.context = new CommandContext();
    }

    /**
     * @method
     * @returns {CommandContext} this.context
     */
    getContext() {
        return this.context;
    }

    /**
     * @method
     * @description Calls the CommandFactory to return a command. If a command is
     * returned, it will try to execute the command.
     */
    process() {
       
        if (this.context.get('action') === undefined) {
            throw new RangeError("No action parameter available in commandContext.");
        }

        if (!(typeof this.context.get('action') === 'string')) {
            throw new Error("Action must be of type 'string'", 1);
        }

        if ((this.context.parameters.action == 'macro') &&
            (typeof (this.context.parameters.macroID) === 'number')) {
            var action = 'macro';
        } else {
            var action = this.context.get('action');
        }

        var cmd = CommandFactory.getCommand(action,
            this.context.parameters.userCommandsRootDir);
        
        //load any available configuration upfront.
        //in single mode this is blocking code and therefore
        //it can be done here.
        //For macros this is done asynchronous in the macro class
        //and handled with a separate promise.
        if (!this.context.parameters.macroID) {//it is a single command

            //get single command configuration (optional)
            try {
                var path = require('path');
                var cfgFileDir = path.dirname(this.context.parameters.userConfigFile);
                var cfgFileName = this.context.parameters.action + ".json";
                var cfgFilePath = path.join(cfgFileDir, cfgFileName);
                var cfg = require(cfgFilePath);
                this.context.parameters.cmdConfiguration = cfg;
            } catch (error) {
                console.warn("Warning! - No config file found for %s-command at: %s ", action, cfgFilePath);
            }
        }
            return cmd.execute(this.context);
    }
}

module.exports = Controller;