/**
 * @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"),
    defaultOptions = require("../conf/default-cli-options"),
    Linter = require("./linter"),
    IgnoredPaths = require("./ignored-paths"),
    Config = require("./config"),
    fileEntryCache = require("file-entry-cache"),
    globUtil = require("./util/glob-util"),
    validator = require("./config/config-validator"),
    stringify = require("json-stable-stringify-without-jsonify"),
    hash = require("./util/hash"),
    ModuleResolver = require("./util/module-resolver"),
    naming = require("./util/naming"),
    pkg = require("../package.json");

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

const resolver = new ModuleResolver();

//------------------------------------------------------------------------------
// Typedefs
//------------------------------------------------------------------------------

/**
 * The options to configure a CLI engine with.
 * @typedef {Object} CLIEngineOptions
 * @property {boolean} allowInlineConfig Enable or disable inline configuration comments.
 * @property {boolean|Object} baseConfig Base config object. True enables recommend rules and environments.
 * @property {boolean} cache Enable result caching.
 * @property {string} cacheLocation The cache file to use instead of .eslintcache.
 * @property {string} configFile The configuration file to use.
 * @property {string} cwd The value to use for the current working directory.
 * @property {string[]} envs An array of environments to load.
 * @property {string[]} extensions An array of file extensions to check.
 * @property {boolean|Function} fix Execute in autofix mode. If a function, should return a boolean.
 * @property {string[]} globals An array of global variables to declare.
 * @property {boolean} ignore False disables use of .eslintignore.
 * @property {string} ignorePath The ignore file to use instead of .eslintignore.
 * @property {string} ignorePattern A glob pattern of files to ignore.
 * @property {boolean} useEslintrc False disables looking for .eslintrc
 * @property {string} parser The name of the parser to use.
 * @property {Object} parserOptions An object of parserOption settings to use.
 * @property {string[]} plugins An array of plugins to load.
 * @property {Object<string,*>} rules An object of rules to use.
 * @property {string[]} rulePaths An array of directories to load custom rules from.
 * @property {boolean} reportUnusedDisableDirectives `true` adds reports for unused eslint-disable directives
 */

/**
 * A linting warning or error.
 * @typedef {Object} LintMessage
 * @property {string} message The message to display to the user.
 */

/**
 * A linting result.
 * @typedef {Object} LintResult
 * @property {string} filePath The path to the file that was linted.
 * @property {LintMessage[]} messages All of the messages for the result.
 * @property {number} errorCount Number of errors for the result.
 * @property {number} warningCount Number of warnings for the result.
 * @property {number} fixableErrorCount Number of fixable errors for the result.
 * @property {number} fixableWarningCount Number of fixable warnings for the result.
 * @property {string=} [source] The source code of the file that was linted.
 * @property {string=} [output] The source code of the file that was linted, with as many fixes applied as possible.
 */

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

/**
 * It will calculate the error and warning count for collection of messages per file
 * @param {Object[]} messages - Collection of messages
 * @returns {Object} Contains the stats
 * @private
 */
function calculateStatsPerFile(messages) {
    return messages.reduce((stat, message) => {
        if (message.fatal || message.severity === 2) {
            stat.errorCount++;
            if (message.fix) {
                stat.fixableErrorCount++;
            }
        } else {
            stat.warningCount++;
            if (message.fix) {
                stat.fixableWarningCount++;
            }
        }
        return stat;
    }, {
        errorCount: 0,
        warningCount: 0,
        fixableErrorCount: 0,
        fixableWarningCount: 0
    });
}

/**
 * It will calculate the error and warning count for collection of results from all files
 * @param {Object[]} results - Collection of messages from all the files
 * @returns {Object} Contains the stats
 * @private
 */
function calculateStatsPerRun(results) {
    return results.reduce((stat, result) => {
        stat.errorCount += result.errorCount;
        stat.warningCount += result.warningCount;
        stat.fixableErrorCount += result.fixableErrorCount;
        stat.fixableWarningCount += result.fixableWarningCount;
        return stat;
    }, {
        errorCount: 0,
        warningCount: 0,
        fixableErrorCount: 0,
        fixableWarningCount: 0
    });
}

/**
 * Processes an source code using ESLint.
 * @param {string} text The source code to check.
 * @param {Object} configHelper The configuration options for ESLint.
 * @param {string} filename An optional string representing the texts filename.
 * @param {boolean|Function} fix Indicates if fixes should be processed.
 * @param {boolean} allowInlineConfig Allow/ignore comments that change config.
 * @param {boolean} reportUnusedDisableDirectives Allow/ignore comments that change config.
 * @param {Linter} linter Linter context
 * @returns {LintResult} The results for linting on this text.
 * @private
 */
function processText(text, configHelper, filename, fix, allowInlineConfig, reportUnusedDisableDirectives, linter) {
    let filePath,
        fileExtension,
        processor;

    if (filename) {
        filePath = path.resolve(filename);
        fileExtension = path.extname(filename);
    }

    const effectiveFilename = filename || "<text>";

    debug(`Linting ${effectiveFilename}`);
    const config = configHelper.getConfig(filePath);

    if (config.plugins) {
        configHelper.plugins.loadAll(config.plugins);
    }

    const loadedPlugins = configHelper.plugins.getAll();

    for (const plugin in loadedPlugins) {
        if (loadedPlugins[plugin].processors && Object.keys(loadedPlugins[plugin].processors).indexOf(fileExtension) >= 0) {
            processor = loadedPlugins[plugin].processors[fileExtension];
            break;
        }
    }

    const autofixingEnabled = typeof fix !== "undefined" && (!processor || processor.supportsAutofix);

    const fixedResult = linter.verifyAndFix(text, config, {
        filename: effectiveFilename,
        allowInlineConfig,
        reportUnusedDisableDirectives,
        fix: !!autofixingEnabled && fix,
        preprocess: processor && (rawText => processor.preprocess(rawText, effectiveFilename)),
        postprocess: processor && (problemLists => processor.postprocess(problemLists, effectiveFilename))
    });

    const stats = calculateStatsPerFile(fixedResult.messages);

    const result = {
        filePath: effectiveFilename,
        messages: fixedResult.messages,
        errorCount: stats.errorCount,
        warningCount: stats.warningCount,
        fixableErrorCount: stats.fixableErrorCount,
        fixableWarningCount: stats.fixableWarningCount
    };

    if (fixedResult.fixed) {
        result.output = fixedResult.output;
    }

    if (result.errorCount + result.warningCount > 0 && typeof result.output === "undefined") {
        result.source = text;
    }

    return result;
}

/**
 * Processes an individual file using ESLint. Files used here are known to
 * exist, so no need to check that here.
 * @param {string} filename The filename of the file being checked.
 * @param {Object} configHelper The configuration options for ESLint.
 * @param {Object} options The CLIEngine options object.
 * @param {Linter} linter Linter context
 * @returns {LintResult} The results for linting on this file.
 * @private
 */
function processFile(filename, configHelper, options, linter) {

    const text = fs.readFileSync(path.resolve(filename), "utf8"),
        result = processText(
            text,
            configHelper,
            filename,
            options.fix,
            options.allowInlineConfig,
            options.reportUnusedDisableDirectives,
            linter
        );

    return result;

}

/**
 * Returns result with warning by ignore settings
 * @param {string} filePath - File path of checked code
 * @param {string} baseDir  - Absolute path of base directory
 * @returns {LintResult} Result with single warning
 * @private
 */
function createIgnoreResult(filePath, baseDir) {
    let message;
    const isHidden = /^\./.test(path.basename(filePath));
    const isInNodeModules = baseDir && path.relative(baseDir, filePath).startsWith("node_modules");
    const isInBowerComponents = baseDir && path.relative(baseDir, filePath).startsWith("bower_components");

    if (isHidden) {
        message = "File ignored by default.  Use a negated ignore pattern (like \"--ignore-pattern '!<relative/path/to/filename>'\") to override.";
    } else if (isInNodeModules) {
        message = "File ignored by default. Use \"--ignore-pattern '!node_modules/*'\" to override.";
    } else if (isInBowerComponents) {
        message = "File ignored by default. Use \"--ignore-pattern '!bower_components/*'\" to override.";
    } else {
        message = "File ignored because of a matching ignore pattern. Use \"--no-ignore\" to override.";
    }

    return {
        filePath: path.resolve(filePath),
        messages: [
            {
                fatal: false,
                severity: 1,
                message
            }
        ],
        errorCount: 0,
        warningCount: 1,
        fixableErrorCount: 0,
        fixableWarningCount: 0
    };
}


/**
 * Checks if the given message is an error message.
 * @param {Object} message The message to check.
 * @returns {boolean} Whether or not the message is an error message.
 * @private
 */
function isErrorMessage(message) {
    return message.severity === 2;
}


/**
 * return the cacheFile to be used by eslint, based on whether the provided parameter is
 * a directory or looks like a directory (ends in `path.sep`), in which case the file
 * name will be the `cacheFile/.cache_hashOfCWD`
 *
 * if cacheFile points to a file or looks like a file then in will just use that file
 *
 * @param {string} cacheFile The name of file to be used to store the cache
 * @param {string} cwd Current working directory
 * @returns {string} the resolved path to the cache file
 */
function getCacheFile(cacheFile, cwd) {

    /*
     * make sure the path separators are normalized for the environment/os
     * keeping the trailing path separator if present
     */
    const normalizedCacheFile = path.normalize(cacheFile);

    const resolvedCacheFile = path.resolve(cwd, normalizedCacheFile);
    const looksLikeADirectory = normalizedCacheFile.slice(-1) === path.sep;

    /**
     * return the name for the cache file in case the provided parameter is a directory
     * @returns {string} the resolved path to the cacheFile
     */
    function getCacheFileForDirectory() {
        return path.join(resolvedCacheFile, `.cache_${hash(cwd)}`);
    }

    let fileStats;

    try {
        fileStats = fs.lstatSync(resolvedCacheFile);
    } catch (ex) {
        fileStats = null;
    }


    /*
     * in case the file exists we need to verify if the provided path
     * is a directory or a file. If it is a directory we want to create a file
     * inside that directory
     */
    if (fileStats) {

        /*
         * is a directory or is a file, but the original file the user provided
         * looks like a directory but `path.resolve` removed the `last path.sep`
         * so we need to still treat this like a directory
         */
        if (fileStats.isDirectory() || looksLikeADirectory) {
            return getCacheFileForDirectory();
        }

        // is file so just use that file
        return resolvedCacheFile;
    }

    /*
     * here we known the file or directory doesn't exist,
     * so we will try to infer if its a directory if it looks like a directory
     * for the current operating system.
     */

    // if the last character passed is a path separator we assume is a directory
    if (looksLikeADirectory) {
        return getCacheFileForDirectory();
    }

    return resolvedCacheFile;
}

const configHashCache = new WeakMap();

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

class CLIEngine {

    /**
     * Creates a new instance of the core CLI engine.
     * @param {CLIEngineOptions} providedOptions The options for this instance.
     * @constructor
     */
    constructor(providedOptions) {

        const options = Object.assign(
            Object.create(null),
            defaultOptions,
            { cwd: process.cwd() },
            providedOptions
        );

        /**
         * Stored options for this instance
         * @type {Object}
         */
        this.options = options;
        this.linter = new Linter();

        if (options.cache) {
            const cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd);

            /**
             * Cache used to avoid operating on files that haven't changed since the
             * last successful execution (e.g., file passed linting with no errors and
             * no warnings).
             * @type {Object}
             */
            this._fileCache = fileEntryCache.create(cacheFile);
        }

        // load in additional rules
        if (this.options.rulePaths) {
            const cwd = this.options.cwd;

            this.options.rulePaths.forEach(rulesdir => {
                debug(`Loading rules from ${rulesdir}`);
                this.linter.rules.load(rulesdir, cwd);
            });
        }

        if (this.options.rules && Object.keys(this.options.rules).length) {
            const loadedRules = this.linter.getRules();

            Object.keys(this.options.rules).forEach(name => {
                validator.validateRuleOptions(loadedRules.get(name), name, this.options.rules[name], "CLI");
            });
        }

        this.config = new Config(this.options, this.linter);
    }

    getRules() {
        return this.linter.getRules();
    }

    /**
     * Returns results that only contains errors.
     * @param {LintResult[]} results The results to filter.
     * @returns {LintResult[]} The filtered results.
     */
    static getErrorResults(results) {
        const filtered = [];

        results.forEach(result => {
            const filteredMessages = result.messages.filter(isErrorMessage);

            if (filteredMessages.length > 0) {
                filtered.push(
                    Object.assign(result, {
                        messages: filteredMessages,
                        errorCount: filteredMessages.length,
                        warningCount: 0,
                        fixableErrorCount: result.fixableErrorCount,
                        fixableWarningCount: 0
                    })
                );
            }
        });

        return filtered;
    }

    /**
     * Outputs fixes from the given results to files.
     * @param {Object} report The report object created by CLIEngine.
     * @returns {void}
     */
    static outputFixes(report) {
        report.results.filter(result => result.hasOwnProperty("output")).forEach(result => {
            fs.writeFileSync(result.filePath, result.output);
        });
    }


    /**
     * Add a plugin by passing its configuration
     * @param {string} name Name of the plugin.
     * @param {Object} pluginobject Plugin configuration object.
     * @returns {void}
     */
    addPlugin(name, pluginobject) {
        this.config.plugins.define(name, pluginobject);
    }

    /**
     * Resolves the patterns passed into executeOnFiles() into glob-based patterns
     * for easier handling.
     * @param {string[]} patterns The file patterns passed on the command line.
     * @returns {string[]} The equivalent glob patterns.
     */
    resolveFileGlobPatterns(patterns) {
        return globUtil.resolveFileGlobPatterns(patterns, this.options);
    }

    /**
     * Executes the current configuration on an array of file and directory names.
     * @param {string[]} patterns An array of file and directory names.
     * @returns {Object} The results for all files that were linted.
     */
    executeOnFiles(patterns) {
        const options = this.options,
            fileCache = this._fileCache,
            configHelper = this.config;
        const cacheFile = getCacheFile(this.options.cacheLocation || this.options.cacheFile, this.options.cwd);

        if (!options.cache && fs.existsSync(cacheFile)) {
            fs.unlinkSync(cacheFile);
        }

        /**
         * Calculates the hash of the config file used to validate a given file
         * @param  {string} filename The path of the file to retrieve a config object for to calculate the hash
         * @returns {string}         the hash of the config
         */
        function hashOfConfigFor(filename) {
            const config = configHelper.getConfig(filename);

            if (!configHashCache.has(config)) {
                configHashCache.set(config, hash(`${pkg.version}_${stringify(config)}`));
            }

            return configHashCache.get(config);
        }

        const startTime = Date.now();
        const fileList = globUtil.listFilesToProcess(this.resolveFileGlobPatterns(patterns), options);
        const results = fileList.map(fileInfo => {
            if (fileInfo.ignored) {
                return createIgnoreResult(fileInfo.filename, options.cwd);
            }

            if (options.cache) {

                /*
                 * get the descriptor for this file
                 * with the metadata and the flag that determines if
                 * the file has changed
                 */
                const descriptor = fileCache.getFileDescriptor(fileInfo.filename);
                const hashOfConfig = hashOfConfigFor(fileInfo.filename);
                const changed = descriptor.changed || descriptor.meta.hashOfConfig !== hashOfConfig;

                if (!changed) {
                    debug(`Skipping file since hasn't changed: ${fileInfo.filename}`);

                    /*
                     * Add the the cached results (always will be 0 error and
                     * 0 warnings). We should not cache results for files that
                     * failed, in order to guarantee that next execution will
                     * process those files as well.
                     */
                    return descriptor.meta.results;
                }
            }

            debug(`Processing ${fileInfo.filename}`);

            return processFile(fileInfo.filename, configHelper, options, this.linter);
        });

        if (options.cache) {
            results.forEach(result => {
                if (result.messages.length) {

                    /*
                     * if a file contains errors or warnings we don't want to
                     * store the file in the cache so we can guarantee that
                     * next execution will also operate on this file
                     */
                    fileCache.removeEntry(result.filePath);
                } else {

                    /*
                     * since the file passed we store the result here
                     * TODO: it might not be necessary to store the results list in the cache,
                     * since it should always be 0 errors/warnings
                     */
                    const descriptor = fileCache.getFileDescriptor(result.filePath);

                    descriptor.meta.hashOfConfig = hashOfConfigFor(result.filePath);
                    descriptor.meta.results = result;
                }
            });

            // persist the cache to disk
            fileCache.reconcile();
        }

        const stats = calculateStatsPerRun(results);

        debug(`Linting complete in: ${Date.now() - startTime}ms`);

        return {
            results,
            errorCount: stats.errorCount,
            warningCount: stats.warningCount,
            fixableErrorCount: stats.fixableErrorCount,
            fixableWarningCount: stats.fixableWarningCount
        };
    }

    /**
     * Executes the current configuration on text.
     * @param {string} text A string of JavaScript code to lint.
     * @param {string} filename An optional string representing the texts filename.
     * @param {boolean} warnIgnored Always warn when a file is ignored
     * @returns {Object} The results for the linting.
     */
    executeOnText(text, filename, warnIgnored) {

        const results = [],
            options = this.options,
            configHelper = this.config,
            ignoredPaths = new IgnoredPaths(options);

        // resolve filename based on options.cwd (for reporting, ignoredPaths also resolves)

        const resolvedFilename = filename && !path.isAbsolute(filename)
            ? path.resolve(options.cwd, filename)
            : filename;

        if (resolvedFilename && ignoredPaths.contains(resolvedFilename)) {
            if (warnIgnored) {
                results.push(createIgnoreResult(resolvedFilename, options.cwd));
            }
        } else {
            results.push(
                processText(
                    text,
                    configHelper,
                    resolvedFilename,
                    options.fix,
                    options.allowInlineConfig,
                    options.reportUnusedDisableDirectives,
                    this.linter
                )
            );
        }

        const stats = calculateStatsPerRun(results);

        return {
            results,
            errorCount: stats.errorCount,
            warningCount: stats.warningCount,
            fixableErrorCount: stats.fixableErrorCount,
            fixableWarningCount: stats.fixableWarningCount
        };
    }

    /**
     * Returns a configuration object for the given file based on the CLI options.
     * This is the same logic used by the ESLint CLI executable to determine
     * configuration for each file it processes.
     * @param {string} filePath The path of the file to retrieve a config object for.
     * @returns {Object} A configuration object for the file.
     */
    getConfigForFile(filePath) {
        const configHelper = this.config;

        return configHelper.getConfig(filePath);
    }

    /**
     * Checks if a given path is ignored by ESLint.
     * @param {string} filePath The path of the file to check.
     * @returns {boolean} Whether or not the given path is ignored.
     */
    isPathIgnored(filePath) {
        const resolvedPath = path.resolve(this.options.cwd, filePath);
        const ignoredPaths = new IgnoredPaths(this.options);

        return ignoredPaths.contains(resolvedPath);
    }

    /**
     * Returns the formatter representing the given format or null if no formatter
     * with the given name can be found.
     * @param {string} [format] The name of the format to load or the path to a
     *      custom formatter.
     * @returns {Function} The formatter function or null if not found.
     */
    getFormatter(format) {

        // default is stylish
        const resolvedFormatName = format || "stylish";

        // only strings are valid formatters
        if (typeof resolvedFormatName === "string") {

            // replace \ with / for Windows compatibility
            const normalizedFormatName = resolvedFormatName.replace(/\\/g, "/");

            const cwd = this.options ? this.options.cwd : process.cwd();
            const namespace = naming.getNamespaceFromTerm(normalizedFormatName);

            let formatterPath;

            // if there's a slash, then it's a file
            if (!namespace && normalizedFormatName.indexOf("/") > -1) {
                formatterPath = path.resolve(cwd, normalizedFormatName);
            } else {
                try {
                    const npmFormat = naming.normalizePackageName(normalizedFormatName, "eslint-formatter");

                    formatterPath = resolver.resolve(npmFormat, `${cwd}/node_modules`);
                } catch (e) {
                    formatterPath = `./formatters/${normalizedFormatName}`;
                }
            }

            try {
                return require(formatterPath);
            } catch (ex) {
                ex.message = `There was a problem loading formatter: ${formatterPath}\nError: ${ex.message}`;
                throw ex;
            }

        } else {
            return null;
        }
    }
}

CLIEngine.version = pkg.version;
CLIEngine.getFormatter = CLIEngine.prototype.getFormatter;

module.exports = CLIEngine;
