"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
var Executor_1 = require("./Executor");
var instrument_1 = require("../instrument");
var util_1 = require("../common/util");
var util_2 = require("../node/util");
var lang_1 = require("@dojo/core/lang");
var Formatter_1 = require("../node/Formatter");
var path_1 = require("path");
var istanbul_1 = require("istanbul");
var Pretty_1 = require("../reporters/Pretty");
var Simple_1 = require("../reporters/Simple");
var Benchmark_1 = require("../reporters/Benchmark");
var Promise_1 = require("@dojo/shim/Promise");
var GenericNode = (function (_super) {
    __extends(GenericNode, _super);
    function GenericNode(config) {
        var _this = _super.call(this, config) || this;
        _this.registerReporter('pretty', Pretty_1.default);
        _this.registerReporter('simple', Simple_1.default);
        _this.registerReporter('benchmark', Benchmark_1.default);
        _this._formatter = new Formatter_1.default(config);
        util_2.reportUncaughtErrors(_this);
        return _this;
    }
    Object.defineProperty(GenericNode.prototype, "environment", {
        get: function () {
            return 'node';
        },
        enumerable: true,
        configurable: true
    });
    GenericNode.prototype.loadScript = function (script) {
        return util_2.loadScript(script);
    };
    GenericNode.prototype._beforeRun = function () {
        var _this = this;
        return _super.prototype._beforeRun.call(this).then(function () {
            var config = _this.config;
            if (_this.config.excludeInstrumentation !== true) {
                _this._setInstrumentationHooks(_this.config.excludeInstrumentation);
            }
            var suite = _this._rootSuite;
            suite.grep = config.grep;
            suite.timeout = config.defaultTimeout;
            suite.bail = config.bail;
        });
    };
    GenericNode.prototype._loadSuites = function (config) {
        config = config || this.config;
        return _super.prototype._loadSuites.call(this, lang_1.deepMixin({}, config, { suites: config.suites.concat(config.nodeSuites) }));
    };
    GenericNode.prototype._processOption = function (name, value) {
        switch (name) {
            case 'nodeSuites':
                this.config[name] = util_1.parseValue(name, value, 'string[]');
                break;
            default:
                _super.prototype._processOption.call(this, name, value);
                break;
        }
    };
    GenericNode.prototype._resolveConfig = function () {
        var _this = this;
        return _super.prototype._resolveConfig.call(this).then(function () {
            var config = _this.config;
            if (!config.basePath) {
                config.basePath = process.cwd() + path_1.sep;
            }
            if (!config.internPath) {
                config.internPath = path_1.dirname(path_1.dirname(__dirname));
            }
            config.internPath = "" + path_1.relative(process.cwd(), config.internPath) + path_1.sep;
            if (config.reporters.length === 0) {
                config.reporters = [{ reporter: 'simple' }];
            }
            if (!config.nodeSuites) {
                config.nodeSuites = [];
            }
            if (config.benchmarkConfig) {
                config.reporters.push({
                    reporter: 'benchmark',
                    options: config.benchmarkConfig
                });
            }
            return Promise_1.default.all(['suites', 'nodeSuites', 'benchmarkSuites'].map(function (property) {
                return util_2.expandFiles(config[property]).then(function (expanded) {
                    config[property] = expanded;
                });
            })).then(function () { return null; });
        });
    };
    GenericNode.prototype._setInstrumentationHooks = function (excludeInstrumentation) {
        var instrumenterOptions = this.config.instrumenterOptions;
        var basePath = util_2.normalizePath("" + path_1.resolve(this.config.basePath || '') + path_1.sep);
        function shouldHook(filename) {
            filename = util_2.normalizePath(filename);
            return filename.indexOf(basePath) === 0 &&
                !excludeInstrumentation.test(filename.slice(basePath.length));
        }
        function instrumentCode(code, filename) {
            return instrument_1.default(code, path_1.resolve(filename), instrumenterOptions);
        }
        istanbul_1.hook.hookRunInThisContext(shouldHook, instrumentCode);
        istanbul_1.hook.hookRequire(shouldHook, instrumentCode);
    };
    GenericNode.prototype._removeInstrumentationHooks = function () {
        istanbul_1.hook.unhookRunInThisContext();
        istanbul_1.hook.unhookRequire();
    };
    return GenericNode;
}(Executor_1.GenericExecutor));
exports.GenericNode = GenericNode;
var Node = (function (_super) {
    __extends(Node, _super);
    function Node() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Node.initialize = function (config) {
        return Executor_1.initialize(Node, config);
    };
    return Node;
}(GenericNode));
exports.default = Node;
//# sourceMappingURL=Node.js.map