#!/usr/bin/env node
"use strict";
var config_1 = require('./config');
var file_utils_1 = require('./file.utils');
var cli_1 = require("./cli");
var input_resolve_1 = require("./input.resolve");
var reporter_resolve_1 = require("./reporter.resolve");
var _ = require('../lodash.custom');
var debug = require('debug')('cb:init');
var availableCommands = {
    run: './command.run',
    r: './command.run',
    tasks: './command.tasks',
    t: './command.tasks',
    ls: './command.tasks',
    watch: './command.watch',
    w: './command.watch',
    watchers: './command.watchers',
    init: './command.init',
    docs: './command.docs',
};
var isCommand = function (input) { return Object.keys(availableCommands).indexOf(input) > -1; };
/**
 * If running from the CLI
 */
if (!module.parent) {
    cli_1.default(handleIncoming);
}
/**
 * Handle any type of init. It could be from the CLI, or via the API.
 * eg, any command from the CLI ultimately ends up in the following call
 *    $  crossbow run task1 -c conf/cb.js
 *    -> handleIncoming({
 *          input: ['run', 'task1'],
 *          flags: {c: 'conf/cb.js'}
 *       });
 */
function handleIncoming(cli, input) {
    var mergedConfig = config_1.merge(cli.flags);
    var userInput = input_resolve_1.getInputs(mergedConfig, input);
    var resolvedReporters = reporter_resolve_1.getReporters(mergedConfig, input);
    var hasReporters = resolvedReporters.valid.length;
    var defaultReporter = reporter_resolve_1.getDefaultReporter();
    // Check if any given reporter are invalid
    // and defer to default
    if (resolvedReporters.invalid.length) {
        defaultReporter(reporter_resolve_1.ReportNames.InvalidReporter, resolvedReporters);
        return;
    }
    // proxy for calling reporter functions.
    // uses default if none given
    var reportFn = function () {
        var args = [];
        for (var _i = 0; _i < arguments.length; _i++) {
            args[_i - 0] = arguments[_i];
        }
        if (!hasReporters) {
            return defaultReporter.apply(null, args);
        }
        resolvedReporters.valid.forEach(function (reporter) {
            reporter.callable.apply(null, args);
        });
    };
    // Bail early if a user tried to load a specific file
    // but it didn't exist, or had some other error
    if (userInput.errors.length) {
        reportFn(reporter_resolve_1.ReportNames.InputError, userInput.sources);
        return;
    }
    // at this point, there are no invalid reporters or input files
    // so we can reset the reporters to anything that may of come in via config
    if (userInput.inputs.length) {
        mergedConfig = config_1.merge(_.merge({}, userInput.inputs[0].config, cli.flags));
    }
    resolvedReporters = reporter_resolve_1.getReporters(mergedConfig, input);
    hasReporters = resolvedReporters.valid.length;
    // Check if any given reporter are invalid
    // and defer to default (again)
    if (resolvedReporters.invalid.length) {
        defaultReporter(reporter_resolve_1.ReportNames.InvalidReporter, resolvedReporters);
        return;
    }
    // Show the user which external inputs are being used
    if (userInput.type === input_resolve_1.InputTypes.ExternalFile ||
        userInput.type === input_resolve_1.InputTypes.CBFile ||
        userInput.type === input_resolve_1.InputTypes.DefaultExternalFile)
        reportFn(reporter_resolve_1.ReportNames.UsingConfigFile, userInput.sources);
    // if the user provided a --cbfile flag, the type 'CBFile'
    // must be available, otherwise this is an error state
    if (userInput.type === input_resolve_1.InputTypes.CBFile) {
        return handleCBfileMode(cli, mergedConfig, reportFn);
    }
    // if the user provided a -c flag, but no external files were
    // returned, this is an error state.
    if (mergedConfig.config.length && userInput.type === input_resolve_1.InputTypes.ExternalFile) {
        return processInput(cli, userInput.inputs[0], mergedConfig, reportFn);
    }
    return processInput(cli, userInput.inputs[0], mergedConfig, reportFn);
}
function handleCBfileMode(cli, config, reportFn) {
    var createFilePaths = file_utils_1.getRequirePaths(config);
    var input = require(createFilePaths.valid[0].resolved);
    input.default.config = processConfigs(_.merge({}, config, input.default.config), cli.flags);
    input.default.cli = cli;
    input.default.reporter = reportFn;
    if (isCommand(cli.input[0])) {
        return require(availableCommands[cli.input[0]]).default.call(null, cli, input.default, input.default.config, reportFn);
    }
    cli.input = ['run'].concat(cli.input);
    return require(availableCommands['run']).default.call(null, cli, input.default, input.default.config, reportFn);
}
/**
 * Now decide who should handle the current command
 */
function processInput(cli, input, config, reportFn) {
    var firstArg = cli.input[0];
    return require(availableCommands[firstArg]).default.call(null, cli, input, config, reportFn);
}
function processConfigs(config, flags) {
    var cbConfig = _.merge({}, config, flags);
    return config_1.merge(cbConfig);
}
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = handleIncoming;
//# sourceMappingURL=index.js.map