"use strict";
var file_utils_1 = require("./file.utils");
var Rx = require('rx');
var logger_1 = require('./logger');
(function (ReporterErrorTypes) {
    ReporterErrorTypes[ReporterErrorTypes["ReporterFileNotFound"] = "ReporterFileNotfound"] = "ReporterFileNotFound";
    ReporterErrorTypes[ReporterErrorTypes["ReporterTypeNotSupported"] = "ReporterTypeNotSupported"] = "ReporterTypeNotSupported";
})(exports.ReporterErrorTypes || (exports.ReporterErrorTypes = {}));
var ReporterErrorTypes = exports.ReporterErrorTypes;
(function (ReporterTypes) {
    ReporterTypes[ReporterTypes["InlineFunction"] = "InlineFunction"] = "InlineFunction";
    ReporterTypes[ReporterTypes["ExternalFile"] = "ExternalFile"] = "ExternalFile";
    ReporterTypes[ReporterTypes["UnsupportedValue"] = "UnsupportedValue"] = "UnsupportedValue";
    ReporterTypes[ReporterTypes["Muted"] = "Muted"] = "Muted";
})(exports.ReporterTypes || (exports.ReporterTypes = {}));
var ReporterTypes = exports.ReporterTypes;
(function (ReportTypes) {
    ReportTypes[ReportTypes["DuplicateInputFile"] = "DuplicateInputFile"] = "DuplicateInputFile";
    ReportTypes[ReportTypes["InputFileCreated"] = "InputFileCreated"] = "InputFileCreated";
    ReportTypes[ReportTypes["InitInputFileTypeNotSupported"] = "InitInputFileTypeNotSupported"] = "InitInputFileTypeNotSupported";
    ReportTypes[ReportTypes["InputError"] = "InputError"] = "InputError";
    ReportTypes[ReportTypes["InputFileNotFound"] = "InputFileNotFound"] = "InputFileNotFound";
    ReportTypes[ReportTypes["InvalidReporter"] = "InvalidReporter"] = "InvalidReporter";
    ReportTypes[ReportTypes["UsingInputFile"] = "UsingInputFile"] = "UsingInputFile";
    ReportTypes[ReportTypes["TaskList"] = "TaskList"] = "TaskList";
    ReportTypes[ReportTypes["TaskTree"] = "TaskTree"] = "TaskTree";
    ReportTypes[ReportTypes["TaskErrors"] = "TaskErrors"] = "TaskErrors";
    ReportTypes[ReportTypes["TaskReport"] = "TaskReport"] = "TaskReport";
    ReportTypes[ReportTypes["NoTasksAvailable"] = "NoTasksAvailable"] = "NoTasksAvailable";
    ReportTypes[ReportTypes["NoTasksProvided"] = "NoTasksProvided"] = "NoTasksProvided";
    ReportTypes[ReportTypes["SimpleTaskList"] = "SimpleTaskList"] = "SimpleTaskList";
    ReportTypes[ReportTypes["BeforeWatchTaskErrors"] = "BeforeWatchTaskErrors"] = "BeforeWatchTaskErrors";
    ReportTypes[ReportTypes["BeforeTaskList"] = "BeforeTaskList"] = "BeforeTaskList";
    ReportTypes[ReportTypes["BeforeTasksDidNotComplete"] = "BeforeTasksDidNotComplete"] = "BeforeTasksDidNotComplete";
    ReportTypes[ReportTypes["BeforeTasksSummary"] = "BeforeTasksSummary"] = "BeforeTasksSummary";
    ReportTypes[ReportTypes["WatchTaskTasksErrors"] = "WatchTaskTasksErrors"] = "WatchTaskTasksErrors";
    ReportTypes[ReportTypes["WatchTaskErrors"] = "WatchTaskErrors"] = "WatchTaskErrors";
    ReportTypes[ReportTypes["WatchTaskReport"] = "WatchTaskReport"] = "WatchTaskReport";
    ReportTypes[ReportTypes["NoFilesMatched"] = "NoFilesMatched"] = "NoFilesMatched";
    ReportTypes[ReportTypes["NoWatchersAvailable"] = "NoWatchersAvailable"] = "NoWatchersAvailable";
    ReportTypes[ReportTypes["NoWatchTasksProvided"] = "NoWatchTasksProvided"] = "NoWatchTasksProvided";
    ReportTypes[ReportTypes["Watchers"] = "Watchers"] = "Watchers";
    ReportTypes[ReportTypes["WatcherNames"] = "WatcherNames"] = "WatcherNames";
    ReportTypes[ReportTypes["WatcherTriggeredTasksCompleted"] = "WatcherTriggeredTasksCompleted"] = "WatcherTriggeredTasksCompleted";
    ReportTypes[ReportTypes["WatcherTriggeredTasks"] = "WatcherTriggeredTasks"] = "WatcherTriggeredTasks";
    ReportTypes[ReportTypes["WatcherSummary"] = "WatcherSummary"] = "WatcherSummary";
    ReportTypes[ReportTypes["DocsAddedToFile"] = "DocsAddedToFile"] = "DocsAddedToFile";
    ReportTypes[ReportTypes["DocsGenerated"] = "DocsMarkdownGenerated"] = "DocsGenerated";
    ReportTypes[ReportTypes["DocsInputFileNotFound"] = "DocsInputFileNotFound"] = "DocsInputFileNotFound";
    ReportTypes[ReportTypes["DocsOutputFileExists"] = "DocsOutputFileExists"] = "DocsOutputFileExists";
    ReportTypes[ReportTypes["DocsInvalidTasksSimple"] = "DocsInvalidTasksSimple"] = "DocsInvalidTasksSimple";
    ReportTypes[ReportTypes["HashDirError"] = "HashDirError"] = "HashDirError";
    ReportTypes[ReportTypes["Summary"] = "Summary"] = "Summary";
    ReportTypes[ReportTypes["SignalReceived"] = "SignalReceived"] = "SignalReceived";
    ReportTypes[ReportTypes["CLIParserOutput"] = "CLIParserOutput"] = "CLIParserOutput";
})(exports.ReportTypes || (exports.ReportTypes = {}));
var ReportTypes = exports.ReportTypes;
function getReporters(config, input) {
    var reporters = (function () {
        /**
         * If --outputOnly (-q) was given, the user wants NO
         * output, other than output from child processes - this
         * is used for shell expansion within other tasks where
         * the 'using crossbow.yaml' or completions summaries are
         * unwanted.
         */
        if (config.outputOnly) {
            return [{
                    type: ReporterTypes.Muted,
                    callable: function () { },
                    errors: [],
                    sources: []
                }];
        }
        /**
         * At this point, a user may of provided a string (as a path to lookup)
         * or a function directly, so we use those to resolve the reporters.
         */
        return [].concat(config.reporters).map(getOneReporter);
    })();
    return {
        all: reporters,
        valid: reporters.filter(function (x) { return x.errors.length === 0; }),
        invalid: reporters.filter(function (x) { return x.errors.length > 0; })
    };
    function getOneReporter(reporter) {
        /**
         * If a function was given as a reported (eg: inline)
         * then it's ALWAYS a valid reporter
         */
        if (typeof reporter === 'function') {
            return {
                type: ReporterTypes.InlineFunction,
                callable: reporter,
                errors: [],
                sources: []
            };
        }
        /**
         * If the reporter was not a string or function
         * it's definitely an unsupported type
         */
        if (typeof reporter !== 'string') {
            return {
                type: ReporterTypes.UnsupportedValue,
                errors: [{ type: ReporterErrorTypes.ReporterTypeNotSupported }],
                sources: [reporter]
            };
        }
        var files = file_utils_1.readFilesFromDisk([reporter], config.cwd);
        var errors = files
            .reduce(function (acc, item) {
            // Convert errors from reading files
            // into errors about reporters
            // This is for correct context in logging
            if (item.errors.length) {
                return acc.concat({
                    type: ReporterErrorTypes.ReporterFileNotFound,
                    file: item
                });
            }
            return acc;
        }, []);
        /**
         * If any errors occurred, return them
         */
        if (errors.length) {
            return {
                type: ReporterTypes.ExternalFile,
                errors: errors,
                sources: files
            };
        }
        /**
         * Now try to 'require' the module. If it
         * does not contain a default export, create an error
         */
        var callable = require(files[0].resolved);
        if (typeof callable !== "function") {
            return {
                type: ReporterTypes.UnsupportedValue,
                errors: [{ type: ReporterErrorTypes.ReporterTypeNotSupported }],
                sources: [files[0]]
            };
        }
        /**
         * Here we have a valid external file to return
         * as a single reporter
         */
        return {
            type: ReporterTypes.ExternalFile,
            callable: callable,
            errors: [],
            sources: files
        };
    }
}
exports.getReporters = getReporters;
function getOutputObserver(mergedConfig, outputObserver) {
    /**
     * If an outputObserver was passed in with configuration (flags)
     */
    if (mergedConfig.outputObserver) {
        return mergedConfig.outputObserver;
    }
    /**
     * If an output observer was passed in via initial setup (cli fallback)
     */
    if (outputObserver) {
        return outputObserver;
    }
    /**
     * Default is to log each report to the console
     */
    var defaultOutputObserver = new Rx.Subject();
    defaultOutputObserver.subscribe(function (xs) {
        xs.data.forEach(function (x) {
            logger_1.default.info(x);
        });
    });
    return defaultOutputObserver;
}
exports.getOutputObserver = getOutputObserver;
function getSignalReporter(mergedConfig, signalObserver) {
    /**
     * If an outputObserver was passed in with configuration (flags)
     */
    if (mergedConfig.signalObserver) {
        return mergedConfig.signalObserver;
    }
    /**
     * If an output observer was passed in via initial setup (cli fallback)
     */
    if (signalObserver) {
        return signalObserver;
    }
    /**
     * Default is to log each report to the console
     */
    var defaultSignalObserver = new Rx.Subject();
    defaultSignalObserver.subscribe(function (signal) {
        // default signals are no-ops
    });
    return defaultSignalObserver;
}
exports.getSignalReporter = getSignalReporter;
function getDefaultReporter() {
    return require('./reporters/defaultReporter').default;
}
exports.getDefaultReporter = getDefaultReporter;
//# sourceMappingURL=reporter.resolve.js.map