(function (factory) {
    if (typeof module === "object" && typeof module.exports === "object") {
        var v = factory(require, exports);
        if (v !== undefined) module.exports = v;
    }
    else if (typeof define === "function" && define.amd) {
        define(["require", "exports", "@dojo/shim/global"], factory);
    }
})(function (require, exports) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var global_1 = require("@dojo/shim/global");
    /**
     * This is a base class for reporters that provides convenienience features such as event handler registration and a
     * default console.
     */
    var Reporter = (function () {
        function Reporter(executor, options) {
            if (options === void 0) { options = {}; }
            if (options.output) {
                this.output = options.output;
            }
            if (options.console) {
                this.console = options.console;
            }
            this.executor = executor;
            this._registerEventHandlers();
        }
        Object.defineProperty(Reporter.prototype, "console", {
            get: function () {
                if (!this._console) {
                    this._console = getConsole();
                }
                return this._console;
            },
            set: function (value) {
                this._console = value;
            },
            enumerable: true,
            configurable: true
        });
        Object.defineProperty(Reporter.prototype, "output", {
            get: function () {
                if (!this._output) {
                    // Use process.stdout in a Node.js environment, otherwise construct a writable-like object that outputs to
                    // the console.
                    if (global_1.default.process != null) {
                        return global_1.default.process.stdout;
                    }
                    else {
                        var _console_1 = this.console;
                        this._output = {
                            write: function (chunk, _encoding, callback) {
                                _console_1.log(chunk);
                                callback();
                            },
                            end: function (chunk, _encoding, callback) {
                                _console_1.log(chunk);
                                callback();
                            }
                        };
                    }
                }
                return this._output;
            },
            set: function (value) {
                this._output = value;
            },
            enumerable: true,
            configurable: true
        });
        Reporter.prototype.formatError = function (error, options) {
            return this.executor.formatError(error, options);
        };
        /**
         * Register any handlers added to the class event handlers map
         */
        Reporter.prototype._registerEventHandlers = function () {
            var _this = this;
            if (!this._eventHandlers) {
                return;
            }
            var _loop_1 = function (name_1) {
                this_1.executor.on(name_1, function () {
                    var args = [];
                    for (var _i = 0; _i < arguments.length; _i++) {
                        args[_i] = arguments[_i];
                    }
                    var handler = _this._eventHandlers[name_1];
                    return (_a = _this)[handler].apply(_a, args);
                    var _a;
                });
            };
            var this_1 = this;
            // Use a for..in loop because _eventHandlers may inherit from a parent
            for (var name_1 in this._eventHandlers) {
                _loop_1(name_1);
            }
        };
        return Reporter;
    }());
    exports.default = Reporter;
    /**
     * Create a decorator that will add a decorated method to a class's list of event handlers.
     */
    function createEventHandler() {
        return function (name) {
            return function (target, propertyKey, _descriptor) {
                if (!target.hasOwnProperty('_eventHandlers')) {
                    if (target._eventHandlers != null) {
                        // If there's an _eventHandlers property on a parent, inherit from it
                        target._eventHandlers = Object.create(target._eventHandlers);
                    }
                    else {
                        target._eventHandlers = {};
                    }
                }
                target._eventHandlers[name || propertyKey] = propertyKey;
            };
        };
    }
    exports.createEventHandler = createEventHandler;
    /**
     * The default event handler decorator.
     */
    exports.eventHandler = createEventHandler();
    function getConsole() {
        if (typeof console !== 'undefined') {
            return console;
        }
        return {
            assert: noop,
            count: noop,
            dir: noop,
            error: noop,
            exception: noop,
            info: noop,
            log: noop,
            table: noop,
            time: noop,
            timeEnd: noop,
            trace: noop,
            warn: noop
        };
    }
    function noop() {
        // do nothing
    }
});
//# sourceMappingURL=Reporter.js.map