"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var arrayUtils = require("../../utils/array");
var pathUtils = require("../../utils/path");
var patternUtils = require("../../utils/pattern");
var DeepFilter = /** @class */ (function () {
    function DeepFilter(options, micromatchOptions) {
        this.options = options;
        this.micromatchOptions = micromatchOptions;
    }
    /**
     * Returns filter for directories.
     */
    DeepFilter.prototype.getFilter = function (positive, negative) {
        var _this = this;
        var depth = this.getMaxDeth(positive);
        var negativeRe = patternUtils.convertPatternsToRe(negative, this.micromatchOptions);
        return function (entry) { return _this.filter(entry, negativeRe, depth); };
    };
    /**
     * Returns true if directory must be read.
     */
    DeepFilter.prototype.filter = function (entry, negativeRe, depth) {
        // Skip reading, depending on the nesting level
        if (!this.options.deep || this.skipByDeepOption(entry) || this.skipByPatternDepth(entry, depth)) {
            return false;
        }
        // Skip reading if the directory is symlink and we don't want expand symlinks
        if (this.isFollowedSymlink(entry)) {
            return false;
        }
        // Skip reading if the directory name starting with a period and is not expected
        if (this.isFollowedDotDirectory(entry)) {
            return false;
        }
        // Skip by negative patterns
        if (patternUtils.matchAny(entry.path, negativeRe)) {
            return false;
        }
        return true;
    };
    /**
     * Returns max depth for reading.
     */
    DeepFilter.prototype.getMaxDeth = function (positive) {
        var globstar = positive.some(patternUtils.hasGlobStar);
        var patternDepths = positive.map(patternUtils.getDepth);
        return globstar ? Infinity : arrayUtils.max(patternDepths);
    };
    /**
     * Returns true for dot directories if the «dot» option is enabled.
     */
    DeepFilter.prototype.isFollowedDotDirectory = function (entry) {
        return !this.options.dot && pathUtils.isDotDirectory(entry.path);
    };
    /**
     * Returns true for symlinked directories if the «followSymlinks» option is enabled.
     */
    DeepFilter.prototype.isFollowedSymlink = function (entry) {
        return !this.options.followSymlinkedDirectories && entry.isSymbolicLink();
    };
    /**
     * Returns true when the «deep» options is number and entry depth greater that the option value.
     */
    DeepFilter.prototype.skipByDeepOption = function (entry) {
        return typeof this.options.deep === 'number' && entry.depth > this.options.deep;
    };
    /**
     * Return true when depth parameter is not an Infinity and entry depth greater that the parameter value.
     */
    DeepFilter.prototype.skipByPatternDepth = function (entry, depth) {
        return depth !== Infinity && entry.depth > depth;
    };
    return DeepFilter;
}());
exports.default = DeepFilter;
