"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const utils = require("../../utils");
class DeepFilter {
    constructor(_settings, _micromatchOptions) {
        this._settings = _settings;
        this._micromatchOptions = _micromatchOptions;
    }
    getFilter(basePath, positive, negative) {
        const maxPatternDepth = this._getMaxPatternDepth(positive);
        const negativeRe = this._getNegativePatternsRe(negative);
        return (entry) => this._filter(basePath, entry, negativeRe, maxPatternDepth);
    }
    _getMaxPatternDepth(patterns) {
        const globstar = patterns.some(utils.pattern.hasGlobStar);
        return globstar ? Infinity : utils.pattern.getMaxNaivePatternsDepth(patterns);
    }
    _getNegativePatternsRe(patterns) {
        const affectDepthOfReadingPatterns = patterns.filter(utils.pattern.isAffectDepthOfReadingPattern);
        return utils.pattern.convertPatternsToRe(affectDepthOfReadingPatterns, this._micromatchOptions);
    }
    _filter(basePath, entry, negativeRe, maxPatternDepth) {
        const depth = this._getEntryDepth(basePath, entry.path);
        if (this._isSkippedByDeep(depth)) {
            return false;
        }
        if (this._isSkippedByMaxPatternDepth(depth, maxPatternDepth)) {
            return false;
        }
        if (this._isSkippedSymbolicLink(entry)) {
            return false;
        }
        return this._isSkippedByNegativePatterns(entry, negativeRe);
    }
    _getEntryDepth(basePath, entryPath) {
        const basePathDepth = basePath.split('/').length;
        const entryPathDepth = entryPath.split('/').length;
        return entryPathDepth - (basePath === '' ? 0 : basePathDepth);
    }
    _isSkippedByDeep(entryDepth) {
        return entryDepth >= this._settings.deep;
    }
    _isSkippedByMaxPatternDepth(entryDepth, maxPatternDepth) {
        return !this._settings.baseNameMatch && maxPatternDepth !== Infinity && entryDepth > maxPatternDepth;
    }
    _isSkippedSymbolicLink(entry) {
        return !this._settings.followSymbolicLinks && entry.dirent.isSymbolicLink();
    }
    _isSkippedByNegativePatterns(entry, negativeRe) {
        return !utils.pattern.matchAny(entry.path, negativeRe);
    }
}
exports.default = DeepFilter;
