"use strict";
var task_resolve_1 = require("./task.resolve");
var task_utils_1 = require("./task.utils");
var _ = require('../lodash.custom');
(function (TaskErrorTypes) {
    TaskErrorTypes[TaskErrorTypes["TaskNotFound"] = "TaskNotFound"] = "TaskNotFound";
    TaskErrorTypes[TaskErrorTypes["SubtasksNotInConfig"] = "SubtasksNotInConfig"] = "SubtasksNotInConfig";
    TaskErrorTypes[TaskErrorTypes["SubtaskNotProvided"] = "SubtaskNotProvided"] = "SubtaskNotProvided";
    TaskErrorTypes[TaskErrorTypes["SubtaskNotFound"] = "SubtaskNotFound"] = "SubtaskNotFound";
    TaskErrorTypes[TaskErrorTypes["SubtaskWildcardNotAvailable"] = "SubtaskWildcardNotAvailable"] = "SubtaskWildcardNotAvailable";
    TaskErrorTypes[TaskErrorTypes["AdaptorNotFound"] = "AdaptorNotFound"] = "AdaptorNotFound";
    TaskErrorTypes[TaskErrorTypes["FlagNotFound"] = "FlagNotFound"] = "FlagNotFound";
    TaskErrorTypes[TaskErrorTypes["CBFlagNotProvided"] = "CBFlagNotProvided"] = "CBFlagNotProvided";
    TaskErrorTypes[TaskErrorTypes["InvalidTaskInput"] = "InvalidTaskInput"] = "InvalidTaskInput";
    TaskErrorTypes[TaskErrorTypes["CircularReference"] = "CircularReference"] = "CircularReference";
    TaskErrorTypes[TaskErrorTypes["FileTypeNotSupported"] = "FileTypeNotSupported"] = "FileTypeNotSupported";
})(exports.TaskErrorTypes || (exports.TaskErrorTypes = {}));
var TaskErrorTypes = exports.TaskErrorTypes;
function gatherTaskErrors(task, trigger) {
    return [
        getModuleErrors,
        getFileTypeErrors,
        getCBFlagErrors,
        getSubTaskErrors
    ].reduce(function (all, fn) { return all.concat(fn(task, trigger)); }, []);
}
exports.gatherTaskErrors = gatherTaskErrors;
function getModuleErrors(task, trigger) {
    if (task.type === task_resolve_1.TaskTypes.ExternalTask)
        return [];
    if (task.type === task_resolve_1.TaskTypes.InlineFunction)
        return [];
    /**
     * If a module was not located, and there are 0 child tasks,
     * this can be classified as a `module not found error`
     */
    if (task.externalTasks.length === 0 && task.tasks.length === 0) {
        return [{
                type: TaskErrorTypes.TaskNotFound,
                taskName: task.taskName,
                cwd: trigger.config.cwd
            }];
    }
    return [];
}
function getFileTypeErrors(task, trigger) {
    /**
     * If it's not an external task, this can never be an error
     */
    if (task.type !== task_resolve_1.TaskTypes.ExternalTask)
        return [];
    var supported = task_utils_1.isSupportedFileType(task.externalTasks[0].parsed.ext);
    if (supported)
        return [];
    return [{ type: TaskErrorTypes.FileTypeNotSupported, taskName: task.taskName, externalFile: task.externalTasks[0] }];
}
function getCBFlagErrors(task, trigger) {
    return task.cbflags.reduce(function (all, flag) {
        /**
         * if `flag` is an empty string, the user provided an @ after a task
         * name, but without the right-hand part.
         * eg:
         *   $ crossbow run build-css@
         *
         * when it should of been
         *   $ crossbow run build-css@p
         *
         */
        if (flag === '') {
            return all.concat({
                type: TaskErrorTypes.CBFlagNotProvided,
                taskName: task.taskName
            });
        }
        return all;
    }, []);
}
function getSubTaskErrors(task, trigger) {
    /**
     * Now validate any subtasks given with colon syntax
     *  eg: sass:dev
     *   -> must have a configuration object under the key sass.dev
     *   -> VALID
     *      config:
     *        sass:
     *          dev: 'input.scss'
     */
    return task.subTasks.reduce(function (all, subTaskName) {
        var configKeys = (function () {
            var taskOptions = Object.keys(_.get(task, "options", {}));
            if (taskOptions.length) {
                return taskOptions;
            }
            return Object.keys(_.get(trigger.input, ['options'].concat(task.baseTaskName), {}));
        })();
        /**
         * if `name` is an empty string, the user provided a colon-separated task
         * name without the right-hand part.
         * eg:
         *   $ crossbow run sass:
         *
         * when it should of been
         *   $ crossbow run sass:site:dev
         *
         */
        if (subTaskName === '') {
            return all.concat({
                type: TaskErrorTypes.SubtaskNotProvided,
                name: subTaskName
            });
        }
        /**
         * if a star was given as a subTask,
         * then this item must have configuration
         * as we'll want to run once with each key
         */
        if (subTaskName === '*') {
            return all.concat(handleWildcardSubtask(configKeys, subTaskName));
        }
        if (!configKeys.length) {
            return all.concat({
                type: TaskErrorTypes.SubtasksNotInConfig,
                name: subTaskName
            });
        }
        /**
         * Finally check if there's configuration that Matches this
         * key.
         */
        var match = _.get(trigger.input, ['options'].concat(task.baseTaskName, subTaskName));
        var match2 = _.get(task, ['options'].concat(subTaskName));
        if (match === undefined && match2 === undefined) {
            return all.concat({
                type: TaskErrorTypes.SubtaskNotFound,
                name: subTaskName
            });
        }
        return all;
    }, []);
}
function handleWildcardSubtask(configKeys, name) {
    if (configKeys.length) {
        return [];
    }
    return [{
            type: TaskErrorTypes.SubtaskWildcardNotAvailable,
            name: name
        }];
}
//# sourceMappingURL=task.errors.js.map