const path = require('path');
const glob = require('glob');
const minimatch = require('minimatch');
const readPkgUp = require('read-pkg-up');
const requireMainFilename = require('require-main-filename');

class TestExclude {
    constructor(opts) {
        Object.assign(
            this,
            {
                cwd: process.cwd(),
                include: false,
                relativePath: true,
                configKey: null, // the key to load config from in package.json.
                configPath: null, // optionally override requireMainFilename.
                configFound: false,
                excludeNodeModules: true,
                extension: false
            },
            opts
        );

        if (typeof this.include === 'string') {
            this.include = [this.include];
        }

        if (typeof this.exclude === 'string') {
            this.exclude = [this.exclude];
        }

        if (typeof this.extension === 'string') {
            this.extension = [this.extension];
        } else if (
            !Array.isArray(this.extension) ||
            this.extension.length === 0
        ) {
            this.extension = false;
        }

        if (!this.include && !this.exclude && this.configKey) {
            Object.assign(this, this.pkgConf(this.configKey, this.configPath));
        }

        if (!this.exclude || !Array.isArray(this.exclude)) {
            this.exclude = exportFunc.defaultExclude;
        }

        if (this.include && this.include.length > 0) {
            this.include = prepGlobPatterns([].concat(this.include));
        } else {
            this.include = false;
        }

        if (
            this.excludeNodeModules &&
            !this.exclude.includes('**/node_modules/**')
        ) {
            this.exclude = this.exclude.concat('**/node_modules/**');
        }

        this.exclude = prepGlobPatterns([].concat(this.exclude));

        this.handleNegation();
    }

    /* handle the special case of negative globs
     * (!**foo/bar); we create a new this.excludeNegated set
     * of rules, which is applied after excludes and we
     * move excluded include rules into this.excludes.
     */
    handleNegation() {
        const noNeg = e => e.charAt(0) !== '!';
        const onlyNeg = e => e.charAt(0) === '!';
        const stripNeg = e => e.slice(1);

        if (Array.isArray(this.include)) {
            const includeNegated = this.include.filter(onlyNeg).map(stripNeg);
            this.exclude.push(...prepGlobPatterns(includeNegated));
            this.include = this.include.filter(noNeg);
        }

        this.excludeNegated = this.exclude.filter(onlyNeg).map(stripNeg);
        this.exclude = this.exclude.filter(noNeg);
        this.excludeNegated = prepGlobPatterns(this.excludeNegated);
    }

    shouldInstrument(filename, relFile) {
        if (
            this.extension &&
            !this.extension.some(ext => filename.endsWith(ext))
        ) {
            return false;
        }

        let pathToCheck = filename;

        if (this.relativePath) {
            relFile = relFile || path.relative(this.cwd, filename);

            // Don't instrument files that are outside of the current working directory.
            if (/^\.\./.test(path.relative(this.cwd, filename))) {
                return false;
            }

            pathToCheck = relFile.replace(/^\.[\\/]/, ''); // remove leading './' or '.\'.
        }

        const dot = { dot: true };
        const matches = pattern => minimatch(pathToCheck, pattern, dot);
        return (
            (!this.include || this.include.some(matches)) &&
            (!this.exclude.some(matches) || this.excludeNegated.some(matches))
        );
    }

    pkgConf(key, path) {
        const cwd = path || requireMainFilename(require);
        const obj = readPkgUp.sync({ cwd });

        if (obj.pkg && obj.pkg[key] && typeof obj.pkg[key] === 'object') {
            this.configFound = true;

            return obj.pkg[key];
        }

        return {};
    }

    globSync(cwd = this.cwd) {
        const globPatterns = getExtensionPattern(this.extension || []);
        const globOptions = { cwd, nodir: true, dot: true };
        /* If we don't have any excludeNegated then we can optimize glob by telling
         * it to not iterate into unwanted directory trees (like node_modules). */
        if (this.excludeNegated.length === 0) {
            globOptions.ignore = this.exclude;
        }

        return glob
            .sync(globPatterns, globOptions)
            .filter(file => this.shouldInstrument(path.resolve(cwd, file)));
    }
}

function prepGlobPatterns(patterns) {
    return patterns.reduce((result, pattern) => {
        // Allow gitignore style of directory exclusion
        if (!/\/\*\*$/.test(pattern)) {
            result = result.concat(pattern.replace(/\/$/, '') + '/**');
        }

        // Any rules of the form **/foo.js, should also match foo.js.
        if (/^\*\*\//.test(pattern)) {
            result = result.concat(pattern.replace(/^\*\*\//, ''));
        }

        return result.concat(pattern);
    }, []);
}

function getExtensionPattern(extension) {
    switch (extension.length) {
        case 0:
            return '**';
        case 1:
            return `**/*${extension[0]}`;
        default:
            return `**/*{${extension.join()}}`;
    }
}

const exportFunc = opts => new TestExclude(opts);

const devConfigs = ['ava', 'babel', 'jest', 'nyc', 'rollup', 'webpack'];

exportFunc.defaultExclude = [
    'coverage/**',
    'packages/*/test/**',
    'test/**',
    'test{,-*}.js',
    '**/*{.,-}test.js',
    '**/__tests__/**',
    `**/{${devConfigs.join()}}.config.js`
];

module.exports = exportFunc;
