/**
 * @file AGLint core
 */
import { type AnyRule } from '@adguard/agtree';
import { type AnySeverity } from './severity';
import { type AnyLinterRule, type LinterConfig, type LinterPosition, type LinterRuleConfig, type LinterRuleConfigObject, type LinterRuleStorage } from './common';
/**
 * Represents a linter result that is returned by the `lint` method
 */
export interface LinterResult {
    /**
     * Array of problems detected by the linter
     */
    problems: LinterProblem[];
    /**
     * Count of warnings (just for convenience, can be calculated from problems array)
     */
    warningCount: number;
    /**
     * Count of errors (just for convenience, can be calculated from problems array)
     */
    errorCount: number;
    /**
     * Count of fatal errors (just for convenience, can be calculated from problems array)
     */
    fatalErrorCount: number;
    /**
     * The fixed filter list content. This is only available if the `fix` option is set to `true`.
     */
    fixed?: string;
}
/**
 * Represents a problem given by the linter
 */
export interface LinterProblem {
    /**
     * Name of the linter rule that generated this problem
     */
    rule?: string;
    /**
     * The severity of this problem (it practically inherits the rule severity)
     */
    severity: AnySeverity;
    /**
     * Text description of the problem
     */
    message: string;
    /**
     * The location of the problem
     */
    position: LinterPosition;
    /**
     * Suggested fix for the problem (if available)
     */
    fix?: AnyRule | AnyRule[];
}
/**
 * Represents a linter rule data object. Basically used internally by the linter,
 * so no need to export this.
 */
export interface LinterRuleData {
    /**
     * The linter rule itself. It's meta provides the rule severity and default config,
     * which can be overridden by the user here.
     */
    rule: AnyLinterRule;
    /**
     * Storage for storing data between events. This storage is only visible
     * to the rule.
     */
    storage: LinterRuleStorage;
    /**
     * Custom config for the rule (it overrides the default config if provided)
     */
    configOverride?: unknown;
    /**
     * Custom severity for the rule (it overrides the default severity if provided)
     */
    severityOverride?: AnySeverity;
}
/**
 * Core linter logic
 */
export declare class Linter {
    /**
     * A map of rule names to `LinterRule` objects
     */
    private readonly rules;
    /**
     * The linter configuration
     */
    private config;
    /**
     * Config presets
     */
    private configPresets;
    /**
     * Creates a new linter instance.
     *
     * @param defaultRules Add default linter rules and config presets to the linter
     * (by default it adds them)
     * @param config Linter config to use (by default it uses the default config)
     */
    constructor(defaultRules?: boolean, config?: LinterConfig);
    /**
     * Adds all default rules to the linter.
     */
    addDefaultRules(): void;
    /**
     * Adds all default config presets to the linter.
     */
    addDefaultConfigPresets(): void;
    /**
     * Sets the config for a given rule. It just overrides the default config.
     *
     * @param ruleName The name of the rule to set the config for
     * @param ruleConfig The config to set
     * @throws If the rule doesn't exist
     * @throws If the rule severity / config is invalid
     * @throws If the rule doesn't support config
     */
    setRuleConfig(ruleName: string, ruleConfig: LinterRuleConfig): void;
    /**
     * This method applies the configuration "rules" part to the linter.
     *
     * @param rulesConfig Rules config object
     */
    applyRulesConfig(rulesConfig: LinterRuleConfigObject): void;
    /**
     * Gets the linter configuration.
     *
     * @returns The linter configuration
     */
    getConfig(): LinterConfig;
    /**
     * Adds a new config preset to the linter.
     *
     * @param name Config preset name, e.g. "aglint:recommended"
     * @param config Related config object
     * @throws If the config preset already exists
     */
    addConfigPreset(name: string, config: LinterConfig): void;
    /**
     * Applies the config presets to the config object (extends the config
     * with the given presets if they exist).
     *
     * @param config Config object
     * @returns Extended config object
     * @throws If the config preset doesn't exist
     * @throws If the config is invalid
     */
    applyConfigExtensions(config: LinterConfig): LinterConfig;
    /**
     * Sets the linter configuration. If `reset` is set to `true`, all rule
     * configurations are reset to their default values (removing overrides).
     *
     * @param config Core linter configuration
     * @param reset Whether to reset all rule configs
     * @throws If any of the config presets doesn't exist
     * @throws If the rule config is invalid in any way
     */
    setConfig(config: LinterConfig, reset?: boolean): void;
    /**
     * Adds a new rule to the linter.
     *
     * @param name The name of the rule
     * @param rule The rule itself
     * @throws If the rule name is already taken
     */
    addRule(name: string, rule: AnyLinterRule): void;
    /**
     * Adds a new rule to the linter, but you can specify the rule data.
     *
     * @param name The name of the rule
     * @param data The rule data, see `LinterRuleData` interface for more details
     * @throws If the rule name is already taken
     * @throws If the rule severity is invalid
     * @throws If the rule config is invalid
     */
    addRuleEx(name: string, data: LinterRuleData): void;
    /**
     * Resets default config for the rule with the specified name.
     *
     * @param name The name of the rule
     * @throws If the rule doesn't exist
     * @throws If the rule doesn't support config
     */
    resetRuleConfig(name: string): void;
    /**
     * Gets the current config for the rule with the specified name.
     *
     * @param name The name of the rule
     * @returns The currently active config for the rule. If no override is set,
     * the default config is returned.
     * @throws If the rule doesn't exist
     * @throws If the rule doesn't support config
     */
    getRuleConfig(name: string): LinterRuleConfig;
    /**
     * Returns the `LinterRule` object with the specified name.
     *
     * @param name - The name of the rule
     * @returns The `LinterRule` object, or `undefined` if no such rule exists
     */
    getRule(name: string): AnyLinterRule | undefined;
    /**
     * Returns the map of all rules in the repository.
     *
     * @returns The map of rule names to `LinterRule` objects
     */
    getRules(): Map<string, LinterRuleData>;
    /**
     * Returns whether a rule with the specified name exists in the repository.
     *
     * @param name - The name of the rule
     * @returns `true` if the rule exists, `false` otherwise
     */
    hasRule(name: string): boolean;
    /**
     * Removes a rule from the repository.
     *
     * @param name - The name of the rule
     */
    removeRule(name: string): void;
    /**
     * Disables a rule by name.
     *
     * @param name - The name of the rule
     * @throws If the rule does not exist
     */
    disableRule(name: string): void;
    /**
     * Enables a rule
     *
     * @param name - The name of the rule
     * @throws If the rule does not exist
     */
    enableRule(name: string): void;
    /**
     * Returns whether a rule is disabled.
     *
     * @param name - The name of the rule
     * @returns `true` if the rule is disabled, `false` otherwise
     */
    isRuleDisabled(name: string): boolean;
    /**
     * Lints the list of rules (typically this is the content of a filter list).
     *
     * @param content - Filter list content
     * @param fix - Include fixes in the result. Please note that if more than one fix
     * is available for a single problem, then the line will be skipped.
     * @returns Linter result
     */
    lint(content: string, fix?: boolean): LinterResult;
}
