/**
 * DomainMatcher provides comprehensive domain matching functionality
 * Supporting exact matches, wildcards, and case-insensitive matching
 */
export class DomainMatcher {
    static wildcardToRegex(pattern) {
        // Escape special regex characters except *
        const escaped = pattern.replace(/[.+?^${}()|[\]\\]/g, '\\$&');
        // Replace * with regex equivalent
        const regexPattern = escaped.replace(/\*/g, '.*');
        return new RegExp(`^${regexPattern}$`, 'i');
    }
    /**
     * Match a domain pattern against a hostname
     * @param pattern The pattern to match (supports wildcards like *.example.com)
     * @param hostname The hostname to test
     * @param options Matching options
     * @returns true if the hostname matches the pattern
     */
    static match(pattern, hostname, options = {}) {
        // Handle null/undefined cases
        if (!pattern || !hostname) {
            return false;
        }
        // Normalize inputs
        const normalizedPattern = pattern.toLowerCase().trim();
        const normalizedHostname = hostname.toLowerCase().trim();
        // Remove trailing dots (FQDN normalization)
        const cleanPattern = normalizedPattern.replace(/\.$/, '');
        const cleanHostname = normalizedHostname.replace(/\.$/, '');
        // Exact match (most common case)
        if (cleanPattern === cleanHostname) {
            return true;
        }
        // Wildcard matching
        if (options.allowWildcards !== false && cleanPattern.includes('*')) {
            const regex = this.wildcardToRegex(cleanPattern);
            return regex.test(cleanHostname);
        }
        // No match
        return false;
    }
    /**
     * Check if a pattern contains wildcards
     */
    static isWildcardPattern(pattern) {
        return pattern.includes('*');
    }
    /**
     * Calculate the specificity of a domain pattern
     * Higher values mean more specific patterns
     */
    static calculateSpecificity(pattern) {
        if (!pattern)
            return 0;
        let score = 0;
        // Exact domains are most specific
        if (!pattern.includes('*')) {
            score += 100;
        }
        // Count domain segments
        const segments = pattern.split('.');
        score += segments.length * 10;
        // Penalize wildcards based on position
        if (pattern.startsWith('*')) {
            score -= 50; // Leading wildcard is very generic
        }
        else if (pattern.includes('*')) {
            score -= 20; // Wildcard elsewhere is less generic
        }
        // Bonus for longer patterns
        score += pattern.length;
        return score;
    }
    /**
     * Find all matching patterns from a list
     * Returns patterns sorted by specificity (most specific first)
     */
    static findAllMatches(patterns, hostname, options = {}) {
        const matches = patterns.filter(pattern => this.match(pattern, hostname, options));
        // Sort by specificity (highest first)
        return matches.sort((a, b) => this.calculateSpecificity(b) - this.calculateSpecificity(a));
    }
    /**
     * Instance method for interface compliance
     */
    match(pattern, hostname, options) {
        return DomainMatcher.match(pattern, hostname, options);
    }
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZG9tYWluLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vdHMvY29yZS9yb3V0aW5nL21hdGNoZXJzL2RvbWFpbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQTs7O0dBR0c7QUFDSCxNQUFNLE9BQU8sYUFBYTtJQUNoQixNQUFNLENBQUMsZUFBZSxDQUFDLE9BQWU7UUFDNUMsMkNBQTJDO1FBQzNDLE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsb0JBQW9CLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUQsa0NBQWtDO1FBQ2xDLE1BQU0sWUFBWSxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2xELE9BQU8sSUFBSSxNQUFNLENBQUMsSUFBSSxZQUFZLEdBQUcsRUFBRSxHQUFHLENBQUMsQ0FBQztJQUM5QyxDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FDVixPQUFlLEVBQ2YsUUFBZ0IsRUFDaEIsVUFBK0IsRUFBRTtRQUVqQyw4QkFBOEI7UUFDOUIsSUFBSSxDQUFDLE9BQU8sSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQzFCLE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztRQUVELG1CQUFtQjtRQUNuQixNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUN2RCxNQUFNLGtCQUFrQixHQUFHLFFBQVEsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUV6RCw0Q0FBNEM7UUFDNUMsTUFBTSxZQUFZLEdBQUcsaUJBQWlCLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsQ0FBQztRQUMxRCxNQUFNLGFBQWEsR0FBRyxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBRTVELGlDQUFpQztRQUNqQyxJQUFJ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