/**
 * @fileoverview Responsible for loading ignore config files and managing ignore patterns
 * @author Jonathan Rajavuori
 */

"use strict";

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

const fs = require("fs"),
    path = require("path"),
    ignore = require("ignore");

const debug = require("debug")("eslint:ignored-paths");

//------------------------------------------------------------------------------
// Constants
//------------------------------------------------------------------------------

const ESLINT_IGNORE_FILENAME = ".eslintignore";

/**
 * Adds `"*"` at the end of `"node_modules/"`,
 * so that subtle directories could be re-included by .gitignore patterns
 * such as `"!node_modules/should_not_ignored"`
 */
const DEFAULT_IGNORE_DIRS = [
    "/node_modules/*",
    "/bower_components/*"
];
const DEFAULT_OPTIONS = {
    dotfiles: false,
    cwd: process.cwd()
};

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

/**
 * Find a file in the current directory.
 * @param {string} cwd Current working directory
 * @param {string} name File name
 * @returns {string} Path of ignore file or an empty string.
 */
function findFile(cwd, name) {
    const ignoreFilePath = path.resolve(cwd, name);

    return fs.existsSync(ignoreFilePath) && fs.statSync(ignoreFilePath).isFile() ? ignoreFilePath : "";
}

/**
 * Find an ignore file in the current directory.
 * @param {string} cwd Current working directory
 * @returns {string} Path of ignore file or an empty string.
 */
function findIgnoreFile(cwd) {
    return findFile(cwd, ESLINT_IGNORE_FILENAME);
}

/**
 * Find an package.json file in the current directory.
 * @param {string} cwd Current working directory
 * @returns {string} Path of package.json file or an empty string.
 */
function findPackageJSONFile(cwd) {
    return findFile(cwd, "package.json");
}

/**
 * Merge options with defaults
 * @param {Object} options Options to merge with DEFAULT_OPTIONS constant
 * @returns {Object} Merged options
 */
function mergeDefaultOptions(options) {
    return Object.assign({}, DEFAULT_OPTIONS, options);
}

/* eslint-disable valid-jsdoc */
/**
 * Normalize the path separators in a given string.
 * On Windows environment, this replaces `\` by `/`.
 * Otherwrise, this does nothing.
 * @param {string} str The path string to normalize.
 * @returns {string} The normalized path.
 */
const normalizePathSeps = path.sep === "/"
    ? (str => str)
    : ((seps, str) => str.replace(seps, "/")).bind(null, new RegExp(`\\${path.sep}`, "gu"));
/* eslint-enable valid-jsdoc */

/**
 * Converts a glob pattern to a new glob pattern relative to a different directory
 * @param {string} globPattern The glob pattern, relative the the old base directory
 * @param {string} relativePathToOldBaseDir A relative path from the new base directory to the old one
 * @returns {string} A glob pattern relative to the new base directory
 */
function relativize(globPattern, relativePathToOldBaseDir) {
    if (relativePathToOldBaseDir === "") {
        return globPattern;
    }

    const prefix = globPattern.startsWith("!") ? "!" : "";
    const globWithoutPrefix = globPattern.replace(/^!/u, "");

    if (globWithoutPrefix.startsWith("/")) {
        return `${prefix}/${normalizePathSeps(relativePathToOldBaseDir)}${globWithoutPrefix}`;
    }

    return globPattern;
}

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

/**
 * IgnoredPaths class
 */
class IgnoredPaths {

    /**
     * @param {Object} providedOptions object containing 'ignore', 'ignorePath' and 'patterns' properties
     */
    constructor(providedOptions) {
        const options = mergeDefaultOptions(providedOptions);

        this.cache = {};

        this.defaultPatterns = [].concat(DEFAULT_IGNORE_DIRS, options.patterns || []);

        this.ignoreFileDir = options.ignore !== false && options.ignorePath
            ? path.dirname(path.resolve(options.cwd, options.ignorePath))
            : options.cwd;
        this.options = options;
        this._baseDir = null;

        this.ig = {
            custom: ignore(),
            default: ignore()
        };

        this.defaultPatterns.forEach(pattern => this.addPatternRelativeToCwd(this.ig.default, pattern));
        if (options.dotfiles !== true) {

            /*
             * ignore files beginning with a dot, but not files in a parent or
             * ancestor directory (which in relative format will begin with `../`).
             */
            this.addPatternRelativeToCwd(this.ig.default, ".*");
            this.addPatternRelativeToCwd(this.ig.default, "!../");
        }

        /*
         * Add a way to keep track of ignored files.  This was present in node-ignore
         * 2.x, but dropped for now as of 3.0.10.
         */
        this.ig.custom.ignoreFiles = [];
        this.ig.default.ignoreFiles = [];

        if (options.ignore !== false) {
            let ignorePath;

            if (options.ignorePath) {
                debug("Using specific ignore file");

                try {
                    const stat = fs.statSync(options.ignorePath);

                    if (!stat.isFile()) {
                        throw new Error(`${options.ignorePath} is not a file`);
                    }
                    ignorePath = options.ignorePath;
                } catch (e) {
                    e.message = `Cannot read ignore file: ${options.ignorePath}\nError: ${e.message}`;
                    throw e;
                }
            } else {
                debug(`Looking for ignore file in ${options.cwd}`);
                ignorePath = findIgnoreFile(options.cwd);

                try {
                    fs.statSync(ignorePath);
                    debug(`Loaded ignore file ${ignorePath}`);
                } catch (e) {
                    debug("Could not find ignore file in cwd");
                }
            }

            if (ignorePath) {
                debug(`Adding ${ignorePath}`);
                this.addIgnoreFile(this.ig.custom, ignorePath);
                this.addIgnoreFile(this.ig.default, ignorePath);
            } else {
                try {

                    // if the ignoreFile does not exist, check package.json for eslintIgnore
                    const packageJSONPath = findPackageJSONFile(options.cwd);

                    if (packageJSONPath) {
                        let packageJSONOptions;

                        try {
                            packageJSONOptions = JSON.parse(fs.readFileSync(packageJSONPath, "utf8"));
                        } catch (e) {
                            debug("Could not read package.json file to check eslintIgnore property");
                            e.messageTemplate = "failed-to-read-json";
                            e.messageData = {
                                path: packageJSONPath,
                                message: e.message
                            };
                            throw e;
                        }

                        if (packageJSONOptions.eslintIgnore) {
                            if (Array.isArray(packageJSONOptions.eslintIgnore)) {
                                packageJSONOptions.eslintIgnore.forEach(pattern => {
                                    this.addPatternRelativeToIgnoreFile(this.ig.custom, pattern);
                                    this.addPatternRelativeToIgnoreFile(this.ig.default, pattern);
                                });
                            } else {
                                throw new TypeError("Package.json eslintIgnore property requires an array of paths");
                            }
                        }
                    }
                } catch (e) {
                    debug("Could not find package.json to check eslintIgnore property");
                    throw e;
                }
            }

            if (options.ignorePattern) {
                this.addPatternRelativeToCwd(this.ig.custom, options.ignorePattern);
                this.addPatternRelativeToCwd(this.ig.default, options.ignorePattern);
            }
        }
    }

    /*
     * If `ignoreFileDir` is a subdirectory of `cwd`, all paths will be normalized to be relative to `cwd`.
     * Otherwise, all paths will be normalized to be relative to `ignoreFileDir`.
     * This ensures that the final normalized ignore rule will not contain `..`, which is forbidden in
     * ignore rules.
     */

    addPatternRelativeToCwd(ig, pattern) {
        const baseDir = this.getBaseDir();
        const cookedPattern = baseDir === this.options.cwd
            ? pattern
            : relativize(pattern, path.relative(baseDir, this.options.cwd));

        ig.addPattern(cookedPattern);
        debug("addPatternRelativeToCwd:\n  original = %j\n  cooked   = %j", pattern, cookedPattern);
    }

    addPatternRelativeToIgnoreFile(ig, pattern) {
        const baseDir = this.getBaseDir();
        const cookedPattern = baseDir === this.ignoreFileDir
            ? pattern
            : relativize(pattern, path.relative(baseDir, this.ignoreFileDir));

        ig.addPattern(cookedPattern);
        debug("addPatternRelativeToIgnoreFile:\n  original = %j\n  cooked   = %j", pattern, cookedPattern);
    }

    // Detect the common ancestor
    getBaseDir() {
        if (!this._baseDir) {
            const a = path.resolve(this.options.cwd);
            const b = path.resolve(this.ignoreFileDir);
            let lastSepPos = 0;

            // Set the shorter one (it's the common ancestor if one includes the other).
            this._baseDir = a.length < b.length ? a : b;

            // Set the common ancestor.
            for (let i = 0; i < a.length && i < b.length; ++i) {
                if (a[i] !== b[i]) {
                    this._baseDir = a.slice(0, lastSepPos);
                    break;
                }
                if (a[i] === path.sep) {
                    lastSepPos = i;
                }
            }

            // If it's only Windows drive letter, it needs \
            if (/^[A-Z]:$/u.test(this._baseDir)) {
                this._baseDir += "\\";
            }

            debug("baseDir = %j", this._baseDir);
        }
        return this._baseDir;
    }

    /**
     * read ignore filepath
     * @param {string} filePath, file to add to ig
     * @returns {Array} raw ignore rules
     */
    readIgnoreFile(filePath) {
        if (typeof this.cache[filePath] === "undefined") {
            this.cache[filePath] = fs.readFileSync(filePath, "utf8").split(/\r?\n/gu).filter(Boolean);
        }
        return this.cache[filePath];
    }

    /**
     * add ignore file to node-ignore instance
     * @param {Object} ig instance of node-ignore
     * @param {string} filePath file to add to ig
     * @returns {void}
     */
    addIgnoreFile(ig, filePath) {
        ig.ignoreFiles.push(filePath);
        this
            .readIgnoreFile(filePath)
            .forEach(ignoreRule => this.addPatternRelativeToIgnoreFile(ig, ignoreRule));
    }

    /**
     * Determine whether a file path is included in the default or custom ignore patterns
     * @param {string} filepath Path to check
     * @param {string} [category=undefined] check 'default', 'custom' or both (undefined)
     * @returns {boolean} true if the file path matches one or more patterns, false otherwise
     */
    contains(filepath, category) {
        const isDir = filepath.endsWith(path.sep) ||
            (path.sep === "\\" && filepath.endsWith("/"));
        let result = false;
        const basePath = this.getBaseDir();
        const absolutePath = path.resolve(this.options.cwd, filepath);
        let relativePath = path.relative(basePath, absolutePath);

        if (relativePath) {
            if (isDir) {
                relativePath += path.sep;
            }
            if (typeof category === "undefined") {
                result =
                    (this.ig.default.filter([relativePath]).length === 0) ||
                    (this.ig.custom.filter([relativePath]).length === 0);
            } else {
                result =
                    (this.ig[category].filter([relativePath]).length === 0);
            }
        }
        debug("contains:");
        debug("  target   = %j", filepath);
        debug("  base     = %j", basePath);
        debug("  relative = %j", relativePath);
        debug("  result   = %j", result);

        return result;

    }
}

module.exports = { IgnoredPaths };
