/**
 * @fileoverview Config initialization wizard.
 * @author Ilya Volodin
 */


"use strict";

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

const util = require("util"),
    path = require("path"),
    inquirer = require("inquirer"),
    ProgressBar = require("progress"),
    semver = require("semver"),
    recConfig = require("../../conf/eslint-recommended"),
    ConfigOps = require("../shared/config-ops"),
    log = require("../shared/logging"),
    ModuleResolver = require("../shared/relative-module-resolver"),
    autoconfig = require("./autoconfig.js"),
    ConfigFile = require("./config-file"),
    npmUtils = require("./npm-utils"),
    { getSourceCodeOfFiles } = require("./source-code-utils");

const debug = require("debug")("eslint:config-initializer");

//------------------------------------------------------------------------------
// Private
//------------------------------------------------------------------------------

const DEFAULT_ECMA_VERSION = 2018;

/* istanbul ignore next: hard to test fs function */
/**
 * Create .eslintrc file in the current working directory
 * @param {Object} config object that contains user's answers
 * @param {string} format The file format to write to.
 * @returns {void}
 */
function writeFile(config, format) {

    // default is .js
    let extname = ".js";

    if (format === "YAML") {
        extname = ".yml";
    } else if (format === "JSON") {
        extname = ".json";
    }

    const installedESLint = config.installedESLint;

    delete config.installedESLint;

    ConfigFile.write(config, `./.eslintrc${extname}`);
    log.info(`Successfully created .eslintrc${extname} file in ${process.cwd()}`);

    if (installedESLint) {
        log.info("ESLint was installed locally. We recommend using this local copy instead of your globally-installed copy.");
    }
}

/**
 * Get the peer dependencies of the given module.
 * This adds the gotten value to cache at the first time, then reuses it.
 * In a process, this function is called twice, but `npmUtils.fetchPeerDependencies` needs to access network which is relatively slow.
 * @param {string} moduleName The module name to get.
 * @returns {Object} The peer dependencies of the given module.
 * This object is the object of `peerDependencies` field of `package.json`.
 * Returns null if npm was not found.
 */
function getPeerDependencies(moduleName) {
    let result = getPeerDependencies.cache.get(moduleName);

    if (!result) {
        log.info(`Checking peerDependencies of ${moduleName}`);

        result = npmUtils.fetchPeerDependencies(moduleName);
        getPeerDependencies.cache.set(moduleName, result);
    }

    return result;
}
getPeerDependencies.cache = new Map();

/**
 * Return necessary plugins, configs, parsers, etc. based on the config
 * @param   {Object} config  config object
 * @param   {boolean} [installESLint=true]  If `false` is given, it does not install eslint.
 * @returns {string[]} An array of modules to be installed.
 */
function getModulesList(config, installESLint) {
    const modules = {};

    // Create a list of modules which should be installed based on config
    if (config.plugins) {
        for (const plugin of config.plugins) {
            modules[`eslint-plugin-${plugin}`] = "latest";
        }
    }
    if (config.extends && config.extends.indexOf("eslint:") === -1) {
        const moduleName = `eslint-config-${config.extends}`;

        modules[moduleName] = "latest";
        Object.assign(
            modules,
            getPeerDependencies(`${moduleName}@latest`)
        );
    }

    if (installESLint === false) {
        delete modules.eslint;
    } else {
        const installStatus = npmUtils.checkDevDeps(["eslint"]);

        // Mark to show messages if it's new installation of eslint.
        if (installStatus.eslint === false) {
            log.info("Local ESLint installation not found.");
            modules.eslint = modules.eslint || "latest";
            config.installedESLint = true;
        }
    }

    return Object.keys(modules).map(name => `${name}@${modules[name]}`);
}

/**
 * Set the `rules` of a config by examining a user's source code
 *
 * Note: This clones the config object and returns a new config to avoid mutating
 * the original config parameter.
 *
 * @param   {Object} answers  answers received from inquirer
 * @param   {Object} config   config object
 * @returns {Object}          config object with configured rules
 */
function configureRules(answers, config) {
    const BAR_TOTAL = 20,
        BAR_SOURCE_CODE_TOTAL = 4,
        newConfig = Object.assign({}, config),
        disabledConfigs = {};
    let sourceCodes,
        registry;

    // Set up a progress bar, as this process can take a long time
    const bar = new ProgressBar("Determining Config: :percent [:bar] :elapseds elapsed, eta :etas ", {
        width: 30,
        total: BAR_TOTAL
    });

    bar.tick(0); // Shows the progress bar

    // Get the SourceCode of all chosen files
    const patterns = answers.patterns.split(/[\s]+/u);

    try {
        sourceCodes = getSourceCodeOfFiles(patterns, { baseConfig: newConfig, useEslintrc: false }, total => {
            bar.tick((BAR_SOURCE_CODE_TOTAL / total));
        });
    } catch (e) {
        log.info("\n");
        throw e;
    }
    const fileQty = Object.keys(sourceCodes).length;

    if (fileQty === 0) {
        log.info("\n");
        throw new Error("Automatic Configuration failed.  No files were able to be parsed.");
    }

    // Create a registry of rule configs
    registry = new autoconfig.Registry();
    registry.populateFromCoreRules();

    // Lint all files with each rule config in the registry
    registry = registry.lintSourceCode(sourceCodes, newConfig, total => {
        bar.tick((BAR_TOTAL - BAR_SOURCE_CODE_TOTAL) / total); // Subtract out ticks used at beginning
    });
    debug(`\nRegistry: ${util.inspect(registry.rules, { depth: null })}`);

    // Create a list of recommended rules, because we don't want to disable them
    const recRules = Object.keys(recConfig.rules).filter(ruleId => ConfigOps.isErrorSeverity(recConfig.rules[ruleId]));

    // Find and disable rules which had no error-free configuration
    const failingRegistry = registry.getFailingRulesRegistry();

    Object.keys(failingRegistry.rules).forEach(ruleId => {

        // If the rule is recommended, set it to error, otherwise disable it
        disabledConfigs[ruleId] = (recRules.indexOf(ruleId) !== -1) ? 2 : 0;
    });

    // Now that we know which rules to disable, strip out configs with errors
    registry = registry.stripFailingConfigs();

    /*
     * If there is only one config that results in no errors for a rule, we should use it.
     * createConfig will only add rules that have one configuration in the registry.
     */
    const singleConfigs = registry.createConfig().rules;

    /*
     * The "sweet spot" for number of options in a config seems to be two (severity plus one option).
     * Very often, a third option (usually an object) is available to address
     * edge cases, exceptions, or unique situations. We will prefer to use a config with
     * specificity of two.
     */
    const specTwoConfigs = registry.filterBySpecificity(2).createConfig().rules;

    // Maybe a specific combination using all three options works
    const specThreeConfigs = registry.filterBySpecificity(3).createConfig().rules;

    // If all else fails, try to use the default (severity only)
    const defaultConfigs = registry.filterBySpecificity(1).createConfig().rules;

    // Combine configs in reverse priority order (later take precedence)
    newConfig.rules = Object.assign({}, disabledConfigs, defaultConfigs, specThreeConfigs, specTwoConfigs, singleConfigs);

    // Make sure progress bar has finished (floating point rounding)
    bar.update(BAR_TOTAL);

    // Log out some stats to let the user know what happened
    const finalRuleIds = Object.keys(newConfig.rules);
    const totalRules = finalRuleIds.length;
    const enabledRules = finalRuleIds.filter(ruleId => (newConfig.rules[ruleId] !== 0)).length;
    const resultMessage = [
        `\nEnabled ${enabledRules} out of ${totalRules}`,
        `rules based on ${fileQty}`,
        `file${(fileQty === 1) ? "." : "s."}`
    ].join(" ");

    log.info(resultMessage);

    ConfigOps.normalizeToStrings(newConfig);
    return newConfig;
}

/**
 * process user's answers and create config object
 * @param {Object} answers answers received from inquirer
 * @returns {Object} config object
 */
function processAnswers(answers) {
    let config = {
        rules: {},
        env: {},
        parserOptions: {},
        extends: []
    };

    // set the latest ECMAScript version
    config.parserOptions.ecmaVersion = DEFAULT_ECMA_VERSION;
    config.env.es6 = true;
    config.globals = {
        Atomics: "readonly",
        SharedArrayBuffer: "readonly"
    };

    // set the module type
    if (answers.moduleType === "esm") {
        config.parserOptions.sourceType = "module";
    } else if (answers.moduleType === "commonjs") {
        config.env.commonjs = true;
    }

    // add in browser and node environments if necessary
    answers.env.forEach(env => {
        config.env[env] = true;
    });

    // add in library information
    if (answers.framework === "react") {
        config.parserOptions.ecmaFeatures = {
            jsx: true
        };
        config.plugins = ["react"];
    } else if (answers.framework === "vue") {
        config.plugins = ["vue"];
        config.extends.push("plugin:vue/essential");
    }

    // setup rules based on problems/style enforcement preferences
    if (answers.purpose === "problems") {
        config.extends.unshift("eslint:recommended");
    } else if (answers.purpose === "style") {
        if (answers.source === "prompt") {
            config.extends.unshift("eslint:recommended");
            config.rules.indent = ["error", answers.indent];
            config.rules.quotes = ["error", answers.quotes];
            config.rules["linebreak-style"] = ["error", answers.linebreak];
            config.rules.semi = ["error", answers.semi ? "always" : "never"];
        } else if (answers.source === "auto") {
            config = configureRules(answers, config);
            config = autoconfig.extendFromRecommended(config);
        }
    }

    // normalize extends
    if (config.extends.length === 0) {
        delete config.extends;
    } else if (config.extends.length === 1) {
        config.extends = config.extends[0];
    }

    ConfigOps.normalizeToStrings(config);
    return config;
}

/**
 * Get the version of the local ESLint.
 * @returns {string|null} The version. If the local ESLint was not found, returns null.
 */
function getLocalESLintVersion() {
    try {
        const eslintPath = ModuleResolver.resolve("eslint", path.join(process.cwd(), "__placeholder__.js"));
        const eslint = require(eslintPath);

        return eslint.linter.version || null;
    } catch (_err) {
        return null;
    }
}

/**
 * Get the shareable config name of the chosen style guide.
 * @param {Object} answers The answers object.
 * @returns {string} The shareable config name.
 */
function getStyleGuideName(answers) {
    if (answers.styleguide === "airbnb" && answers.framework !== "react") {
        return "airbnb-base";
    }
    return answers.styleguide;
}

/**
 * Check whether the local ESLint version conflicts with the required version of the chosen shareable config.
 * @param {Object} answers The answers object.
 * @returns {boolean} `true` if the local ESLint is found then it conflicts with the required version of the chosen shareable config.
 */
function hasESLintVersionConflict(answers) {

    // Get the local ESLint version.
    const localESLintVersion = getLocalESLintVersion();

    if (!localESLintVersion) {
        return false;
    }

    // Get the required range of ESLint version.
    const configName = getStyleGuideName(answers);
    const moduleName = `eslint-config-${configName}@latest`;
    const peerDependencies = getPeerDependencies(moduleName) || {};
    const requiredESLintVersionRange = peerDependencies.eslint;

    if (!requiredESLintVersionRange) {
        return false;
    }

    answers.localESLintVersion = localESLintVersion;
    answers.requiredESLintVersionRange = requiredESLintVersionRange;

    // Check the version.
    if (semver.satisfies(localESLintVersion, requiredESLintVersionRange)) {
        answers.installESLint = false;
        return false;
    }

    return true;
}

/**
 * Install modules.
 * @param   {string[]} modules Modules to be installed.
 * @returns {void}
 */
function installModules(modules) {
    log.info(`Installing ${modules.join(", ")}`);
    npmUtils.installSyncSaveDev(modules);
}

/* istanbul ignore next: no need to test inquirer */
/**
 * Ask user to install modules.
 * @param   {string[]} modules Array of modules to be installed.
 * @param   {boolean} packageJsonExists Indicates if package.json is existed.
 * @returns {Promise} Answer that indicates if user wants to install.
 */
function askInstallModules(modules, packageJsonExists) {

    // If no modules, do nothing.
    if (modules.length === 0) {
        return Promise.resolve();
    }

    log.info("The config that you've selected requires the following dependencies:\n");
    log.info(modules.join(" "));
    return inquirer.prompt([
        {
            type: "confirm",
            name: "executeInstallation",
            message: "Would you like to install them now with npm?",
            default: true,
            when() {
                return modules.length && packageJsonExists;
            }
        }
    ]).then(({ executeInstallation }) => {
        if (executeInstallation) {
            installModules(modules);
        }
    });
}

/* istanbul ignore next: no need to test inquirer */
/**
 * Ask use a few questions on command prompt
 * @returns {Promise} The promise with the result of the prompt
 */
function promptUser() {

    return inquirer.prompt([
        {
            type: "list",
            name: "purpose",
            message: "How would you like to use ESLint?",
            default: "problems",
            choices: [
                { name: "To check syntax only", value: "syntax" },
                { name: "To check syntax and find problems", value: "problems" },
                { name: "To check syntax, find problems, and enforce code style", value: "style" }
            ]
        },
        {
            type: "list",
            name: "moduleType",
            message: "What type of modules does your project use?",
            default: "esm",
            choices: [
                { name: "JavaScript modules (import/export)", value: "esm" },
                { name: "CommonJS (require/exports)", value: "commonjs" },
                { name: "None of these", value: "none" }
            ]
        },
        {
            type: "list",
            name: "framework",
            message: "Which framework does your project use?",
            default: "react",
            choices: [
                { name: "React", value: "react" },
                { name: "Vue.js", value: "vue" },
                { name: "None of these", value: "none" }
            ]
        },
        {
            type: "checkbox",
            name: "env",
            message: "Where does your code run?",
            default: ["browser"],
            choices: [
                { name: "Browser", value: "browser" },
                { name: "Node", value: "node" }
            ]
        },
        {
            type: "list",
            name: "source",
            message: "How would you like to define a style for your project?",
            default: "guide",
            choices: [
                { name: "Use a popular style guide", value: "guide" },
                { name: "Answer questions about your style", value: "prompt" },
                { name: "Inspect your JavaScript file(s)", value: "auto" }
            ],
            when(answers) {
                return answers.purpose === "style";
            }
        },
        {
            type: "list",
            name: "styleguide",
            message: "Which style guide do you want to follow?",
            choices: [
                { name: "Airbnb (https://github.com/airbnb/javascript)", value: "airbnb" },
                { name: "Standard (https://github.com/standard/standard)", value: "standard" },
                { name: "Google (https://github.com/google/eslint-config-google)", value: "google" }
            ],
            when(answers) {
                answers.packageJsonExists = npmUtils.checkPackageJson();
                return answers.source === "guide" && answers.packageJsonExists;
            }
        },
        {
            type: "input",
            name: "patterns",
            message: "Which file(s), path(s), or glob(s) should be examined?",
            when(answers) {
                return (answers.source === "auto");
            },
            validate(input) {
                if (input.trim().length === 0 && input.trim() !== ",") {
                    return "You must tell us what code to examine. Try again.";
                }
                return true;
            }
        },
        {
            type: "list",
            name: "format",
            message: "What format do you want your config file to be in?",
            default: "JavaScript",
            choices: ["JavaScript", "YAML", "JSON"]
        },
        {
            type: "confirm",
            name: "installESLint",
            message(answers) {
                const verb = semver.ltr(answers.localESLintVersion, answers.requiredESLintVersionRange)
                    ? "upgrade"
                    : "downgrade";

                return `The style guide "${answers.styleguide}" requires eslint@${answers.requiredESLintVersionRange}. You are currently using eslint@${answers.localESLintVersion}.\n  Do you want to ${verb}?`;
            },
            default: true,
            when(answers) {
                return answers.source === "guide" && answers.packageJsonExists && hasESLintVersionConflict(answers);
            }
        }
    ]).then(earlyAnswers => {

        // early exit if no style guide is necessary
        if (earlyAnswers.purpose !== "style") {
            const config = processAnswers(earlyAnswers);
            const modules = getModulesList(config);

            return askInstallModules(modules, earlyAnswers.packageJsonExists)
                .then(() => writeFile(config, earlyAnswers.format));
        }

        // early exit if you are using a style guide
        if (earlyAnswers.source === "guide") {
            if (!earlyAnswers.packageJsonExists) {
                log.info("A package.json is necessary to install plugins such as style guides. Run `npm init` to create a package.json file and try again.");
                return void 0;
            }
            if (earlyAnswers.installESLint === false && !semver.satisfies(earlyAnswers.localESLintVersion, earlyAnswers.requiredESLintVersionRange)) {
                log.info(`Note: it might not work since ESLint's version is mismatched with the ${earlyAnswers.styleguide} config.`);
            }
            if (earlyAnswers.styleguide === "airbnb" && earlyAnswers.framework !== "react") {
                earlyAnswers.styleguide = "airbnb-base";
            }

            const config = processAnswers(earlyAnswers);

            if (Array.isArray(config.extends)) {
                config.extends.push(earlyAnswers.styleguide);
            } else if (config.extends) {
                config.extends = [config.extends, earlyAnswers.styleguide];
            } else {
                config.extends = [earlyAnswers.styleguide];
            }

            const modules = getModulesList(config);

            return askInstallModules(modules, earlyAnswers.packageJsonExists)
                .then(() => writeFile(config, earlyAnswers.format));

        }

        if (earlyAnswers.source === "auto") {
            const combinedAnswers = Object.assign({}, earlyAnswers);
            const config = processAnswers(combinedAnswers);
            const modules = getModulesList(config);

            return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
        }

        // continue with the style questions otherwise...
        return inquirer.prompt([
            {
                type: "list",
                name: "indent",
                message: "What style of indentation do you use?",
                default: "tab",
                choices: [{ name: "Tabs", value: "tab" }, { name: "Spaces", value: 4 }]
            },
            {
                type: "list",
                name: "quotes",
                message: "What quotes do you use for strings?",
                default: "double",
                choices: [{ name: "Double", value: "double" }, { name: "Single", value: "single" }]
            },
            {
                type: "list",
                name: "linebreak",
                message: "What line endings do you use?",
                default: "unix",
                choices: [{ name: "Unix", value: "unix" }, { name: "Windows", value: "windows" }]
            },
            {
                type: "confirm",
                name: "semi",
                message: "Do you require semicolons?",
                default: true
            }
        ]).then(answers => {
            const totalAnswers = Object.assign({}, earlyAnswers, answers);

            const config = processAnswers(totalAnswers);
            const modules = getModulesList(config);

            return askInstallModules(modules).then(() => writeFile(config, earlyAnswers.format));
        });
    });
}

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

const init = {
    getModulesList,
    hasESLintVersionConflict,
    installModules,
    processAnswers,
    /* istanbul ignore next */initializeConfig() {
        return promptUser();
    }
};

module.exports = init;
