/**
 * @fileoverview Main CLI object.
 * @author Nicholas C. Zakas
 */

"use strict";

/*
 * The CLI object should *not* call process.exit() directly. It should only return
 * exit codes. This allows other programs to use the CLI object and still control
 * when the program exits.
 */

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

const fs = require("fs"),
    path = require("path"),
    mkdirp = require("mkdirp"),
    { CLIEngine } = require("./cli-engine"),
    options = require("./options"),
    log = require("./shared/logging");

const debug = require("debug")("eslint:cli");

//------------------------------------------------------------------------------
// Helpers
//------------------------------------------------------------------------------

/**
 * Predicate function for whether or not to apply fixes in quiet mode.
 * If a message is a warning, do not apply a fix.
 * @param {LintResult} lintResult The lint result.
 * @returns {boolean} True if the lint message is an error (and thus should be
 * autofixed), false otherwise.
 */
function quietFixPredicate(lintResult) {
    return lintResult.severity === 2;
}

/**
 * Translates the CLI options into the options expected by the CLIEngine.
 * @param {Object} cliOptions The CLI options to translate.
 * @returns {CLIEngineOptions} The options object for the CLIEngine.
 * @private
 */
function translateOptions(cliOptions) {
    return {
        envs: cliOptions.env,
        extensions: cliOptions.ext,
        rules: cliOptions.rule,
        plugins: cliOptions.plugin,
        globals: cliOptions.global,
        ignore: cliOptions.ignore,
        ignorePath: cliOptions.ignorePath,
        ignorePattern: cliOptions.ignorePattern,
        configFile: cliOptions.config,
        rulePaths: cliOptions.rulesdir,
        useEslintrc: cliOptions.eslintrc,
        parser: cliOptions.parser,
        parserOptions: cliOptions.parserOptions,
        cache: cliOptions.cache,
        cacheFile: cliOptions.cacheFile,
        cacheLocation: cliOptions.cacheLocation,
        fix: (cliOptions.fix || cliOptions.fixDryRun) && (cliOptions.quiet ? quietFixPredicate : true),
        fixTypes: cliOptions.fixType,
        allowInlineConfig: cliOptions.inlineConfig,
        reportUnusedDisableDirectives: cliOptions.reportUnusedDisableDirectives,
        resolvePluginsRelativeTo: cliOptions.resolvePluginsRelativeTo
    };
}

/**
 * Outputs the results of the linting.
 * @param {CLIEngine} engine The CLIEngine to use.
 * @param {LintResult[]} results The results to print.
 * @param {string} format The name of the formatter to use or the path to the formatter.
 * @param {string} outputFile The path for the output file.
 * @returns {boolean} True if the printing succeeds, false if not.
 * @private
 */
function printResults(engine, results, format, outputFile) {
    let formatter;
    let rulesMeta;

    try {
        formatter = engine.getFormatter(format);
    } catch (e) {
        log.error(e.message);
        return false;
    }

    const output = formatter(results, {
        get rulesMeta() {
            if (!rulesMeta) {
                rulesMeta = {};
                for (const [ruleId, rule] of engine.getRules()) {
                    rulesMeta[ruleId] = rule.meta;
                }
            }
            return rulesMeta;
        }
    });

    if (output) {
        if (outputFile) {
            const filePath = path.resolve(process.cwd(), outputFile);

            if (fs.existsSync(filePath) && fs.statSync(filePath).isDirectory()) {
                log.error("Cannot write to output file path, it is a directory: %s", outputFile);
                return false;
            }

            try {
                mkdirp.sync(path.dirname(filePath));
                fs.writeFileSync(filePath, output);
            } catch (ex) {
                log.error("There was a problem writing the output file:\n%s", ex);
                return false;
            }
        } else {
            log.info(output);
        }
    }

    return true;

}

//------------------------------------------------------------------------------
// Public Interface
//------------------------------------------------------------------------------

/**
 * Encapsulates all CLI behavior for eslint. Makes it easier to test as well as
 * for other Node.js programs to effectively run the CLI.
 */
const cli = {

    /**
     * Executes the CLI based on an array of arguments that is passed in.
     * @param {string|Array|Object} args The arguments to process.
     * @param {string} [text] The text to lint (used for TTY).
     * @returns {int} The exit code for the operation.
     */
    execute(args, text) {
        if (Array.isArray(args)) {
            debug("CLI args: %o", args.slice(2));
        }

        let currentOptions;

        try {
            currentOptions = options.parse(args);
        } catch (error) {
            log.error(error.message);
            return 2;
        }

        const files = currentOptions._;

        const useStdin = typeof text === "string";

        if (currentOptions.version) { // version from package.json

            log.info(`v${require("../package.json").version}`);

        } else if (currentOptions.printConfig) {
            if (files.length) {
                log.error("The --print-config option must be used with exactly one file name.");
                return 2;
            }
            if (useStdin) {
                log.error("The --print-config option is not available for piped-in code.");
                return 2;
            }

            const engine = new CLIEngine(translateOptions(currentOptions));

            const fileConfig = engine.getConfigForFile(currentOptions.printConfig);

            log.info(JSON.stringify(fileConfig, null, "  "));
            return 0;
        } else if (currentOptions.help || (!files.length && !useStdin)) {

            log.info(options.generateHelp());

        } else {

            debug(`Running on ${useStdin ? "text" : "files"}`);

            if (currentOptions.fix && currentOptions.fixDryRun) {
                log.error("The --fix option and the --fix-dry-run option cannot be used together.");
                return 2;
            }

            if (useStdin && currentOptions.fix) {
                log.error("The --fix option is not available for piped-in code; use --fix-dry-run instead.");
                return 2;
            }

            if (currentOptions.fixType && !currentOptions.fix && !currentOptions.fixDryRun) {
                log.error("The --fix-type option requires either --fix or --fix-dry-run.");
                return 2;
            }

            const engine = new CLIEngine(translateOptions(currentOptions));
            const report = useStdin ? engine.executeOnText(text, currentOptions.stdinFilename, true) : engine.executeOnFiles(files);

            if (currentOptions.fix) {
                debug("Fix mode enabled - applying fixes");
                CLIEngine.outputFixes(report);
            }

            if (currentOptions.quiet) {
                debug("Quiet mode enabled - filtering out warnings");
                report.results = CLIEngine.getErrorResults(report.results);
            }

            if (printResults(engine, report.results, currentOptions.format, currentOptions.outputFile)) {
                const tooManyWarnings = currentOptions.maxWarnings >= 0 && report.warningCount > currentOptions.maxWarnings;

                if (!report.errorCount && tooManyWarnings) {
                    log.error("ESLint found too many warnings (maximum: %s).", currentOptions.maxWarnings);
                }

                return (report.errorCount || tooManyWarnings) ? 1 : 0;
            }
            return 2;


        }

        return 0;
    }
};

module.exports = cli;
