"use strict";
var file = require("./file.utils");
var utils = require("./task.utils");
var file_utils_1 = require("./file.utils");
var Immutable = require('immutable');
var reporter_resolve_1 = require("./reporter.resolve");
var fromJS = Immutable.fromJS, Map = Immutable.Map;
var Rx = require('rx');
/**
 * A task context is just an Immutable Map of key=>value pairs
 * that may be used to provide addition context to the task running
 * environment. This is especially useful in situations where you need
 * to do something that MUST block the task running altogether. An example
 * would be hashing files/directories to determine if a task/group of tasks should
 * run.
 */
function getContext(tasks, trigger) {
    /**
     * Define a list of async actions
     * that must complete before any tasks are executed
     * @type {Array}
     */
    var preExecutionTasks = [
        createHashes
    ];
    /**
     * Now wrap each Function in an observable
     * @type {Rx.Observable<PreExecutionTask>[]}
     */
    var observables = preExecutionTasks.map(function (fn) {
        return Rx.Observable.create(function (obs) {
            fn(tasks, trigger).subscribe(obs);
        });
    });
    /**
     * Run each item in sequence
     * finally producing an Immutable Map from all the gathered values
     */
    return Rx.Observable
        .from(observables)
        .concatAll()
        .toArray()
        .map(function (xs) {
        return (_a = Map({})).mergeDeep.apply(_a, xs.map(function (x) { return fromJS(x); }));
        var _a;
    });
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = getContext;
function createHashes(tasks, trigger) {
    var ifLookups = utils.concatProps(tasks, [], "ifChanged");
    if (!ifLookups.length)
        return Rx.Observable.empty();
    return file.hashItems(ifLookups, trigger.config.cwd)
        .map(function (hashResults) {
        // Send in the marked hashes to the run context
        // so that matching tasks can be ignored
        return {
            "ifChanged": hashResults.markedHashes
        };
    })
        .take(1)
        .catch(function (e) {
        if (e.code === 'ENOTDIR')
            e.type = file_utils_1.HashDirErrorTypes.HashNotADirectory;
        if (e.code === 'ENOENT')
            e.type = file_utils_1.HashDirErrorTypes.HashPathNotFound;
        trigger.reporter(reporter_resolve_1.ReportNames.HashDirError, e, trigger.config.cwd);
        return Rx.Observable.just(Immutable.Map({}));
    });
}
//# sourceMappingURL=command.run.context.js.map