import { type PartialWithUndefined } from '@augment-vir/common';
import { type IsEqual, type RequireExactlyOne } from 'type-fest';
/**
 * Optional options for {@link grep}.
 *
 * @category Internal
 * @category Package : @augment-vir/node
 * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
 */
export type GrepOptions<CountOnly extends boolean = false> = PartialWithUndefined<{
    patternSyntax: RequireExactlyOne<{
        /**
         * -E, --extended-regexp: Interpret PATTERNS as extended regular expressions (EREs, see
         * below).
         */
        extendedRegExp: true;
        /** -F, --fixed-strings: Interpret PATTERNS as fixed strings, not regular expressions. */
        fixedStrings: true;
        /**
         * -G, --basic-regexp: Interpret PATTERNS as basic regular expressions (BREs, see below).
         * This is the default.
         */
        basicRegExp: true;
    }>;
    /**
     * If set to true, sets: -i, --ignore-case: Ignore case distinctions in patterns and input data,
     * so that characters that differ only in case match each other.
     */
    ignoreCase: boolean;
    /** -v, --invert-match: Invert the sense of matching, to select non-matching lines. */
    invertMatch: boolean;
    matchType: RequireExactlyOne<{
        /**
         * -w, --word-regexp: Select only those lines containing matches that form whole words. The
         * test is that the matching substring must either be at the beginning of the line, or
         * preceded by a non-word constituent character. Similarly, it must be either at the end of
         * the line or followed by a non-word constituent character. Word-constituent characters are
         * letters, digits, and the underscore. This option has no effect if -x is also specified.
         */
        wordRegExp: true;
        /**
         * -x, --line-regexp: Select only those matches that exactly match the whole line. For a
         * regular expression pattern, this is like parenthesizing the pattern and then surrounding
         * it with ^ and $.
         */
        lineRegExp: true;
    }>;
    output: RequireExactlyOne<{
        /**
         * -c, --count: Suppress normal output; instead print a count of matching lines for each
         * input file. With the -v, --invert-match option (see above), count non-matching lines.
         */
        countOnly: CountOnly;
        /**
         * -l, --files-with-matches: Suppress normal output; instead print the name of each input
         * file from which output would normally have been printed. Scanning each input file stops
         * upon first match.
         */
        filesOnly: true;
    }>;
    /**
     * --exclude=GLOB: Skip any command-line file with a name suffix that matches the pattern GLOB,
     * using wildcard matching; a name suffix is either the whole name, or a trailing part that
     * starts with a non-slash character immediately after a slash (/) in the name. When searching
     * recursively, skip any subfile whose base name matches GLOB; the base name is the part after
     * the last slash. A pattern can use *, ?, and [...] as wildcards, and \ to quote a wildcard or
     * backslash character literally.
     */
    excludePatterns: string[];
    /**
     * -m NUM, --max-count=NUM: Stop reading a file after NUM matching lines. If NUM is zero, grep
     * stops right away without reading input. A NUM of -1 is treated as infinity and grep does not
     * stop; this is the default. If the input is standard input from a regular file, and NUM
     * matching lines are output, grep ensures that the standard input is positioned to just after
     * the last matching line before exiting, regardless of the presence of trailing context lines.
     * This enables a calling process to resume a search. When grep stops after NUM matching lines,
     * it outputs any trailing context lines. When the -c or --count option is also used, grep does
     * not output a count greater than NUM. When the -v or --invert-match option is also used, grep
     * stops after outputting NUM non-matching lines.
     */
    maxCount: number;
    /**
     * -r, --recursive: Read all files under each directory, recursively, following symbolic links
     * only if they are on the command line. Note that if no file operand is given, grep searches
     * the working directory. This is equivalent to the -d recurse option.
     */
    recursive: boolean;
    /**
     * If `true`, sets `--dereference-recursive` instead of `--recursive` when searching
     * recursively.
     *
     * -R, --dereference-recursive: Read all files under each directory, recursively. Follow all
     * symbolic links, unlike -r.
     */
    followSymLinks: boolean;
    /**
     * -U, --binary: Treat the file(s) as binary. By default, under MS-DOS and MS-Windows, grep
     * guesses whether a file is text or binary as described for the --binary-files option. If grep
     * decides the file is a text file, it strips the CR characters from the original file contents
     * (to make regular expressions with ^ and $ work correctly). Specifying -U overrules this
     * guesswork, causing all files to be read and passed to the matching mechanism verbatim; if the
     * file is a text file with CR/LF pairs at the end of each line, this will cause some regular
     * expressions to fail. This option has no effect on platforms other than MS-DOS and MS-
     * Windows.
     */
    binary: boolean;
    /**
     * --exclude-dir=GLOB: Skip any command-line directory with a name suffix that matches the
     * pattern GLOB. When searching recursively, skip any subdirectory whose base name matches GLOB.
     * Ignore any redundant trailing slashes in GLOB.
     */
    excludeDirs: string[];
    /**
     * --include=GLOB: Search only files whose base name matches GLOB (using wildcard matching as
     * described under --exclude). If contradictory --include and --exclude options are given, the
     * last matching one wins. If no --include or --exclude options match, a file is included unless
     * the first such option is --include.
     */
    includeFiles: string[];
    /** Debugging option: if set to `true`, the grep CLI command will be printed before execution. */
    printCommand: boolean;
    /** The directory where the grep command where be run within. */
    cwd: string;
}>;
/**
 * Search location options for {@link grep}.
 *
 * @category Internal
 * @category Package : @augment-vir/node
 * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
 */
export type GrepSearchLocation = RequireExactlyOne<{
    /** Search within multiple files. */
    files: string[];
    /**
     * Search within multiple directories. Set `recursive` to `true` in options to search the
     * directory recursively.
     */
    dirs: string[];
    /**
     * Search within a single directory. Set `recursive` to `true` in options to search the
     * directory recursively.
     */
    dir: string;
    /** Search within a single file. */
    file: string;
}>;
/**
 * Search pattern options for {@link grep}.
 *
 * @category Internal
 * @category Package : @augment-vir/node
 * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
 */
export type GrepSearchPattern = RequireExactlyOne<{
    pattern: string;
    patterns: string[];
}>;
/**
 * Output of {@link grep}. Each key is a file path returned by `grep`. Values are arrays of matched
 * lines for that file.
 *
 * @category Internal
 * @category Package : @augment-vir/node
 * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
 */
export type GrepMatches<CountOnly extends boolean = false> = IsEqual<CountOnly, true> extends true ? {
    [FileName in string]: number;
} : IsEqual<CountOnly, false> extends true ? {
    [FileName in string]: string[];
} : {
    [FileName in string]: number;
} | {
    [FileName in string]: string[];
};
/**
 * Run `grep`, matching patterns to specific lines in files or directories.
 *
 * @category Node : File
 * @category Package : @augment-vir/node
 * @package [`@augment-vir/node`](https://www.npmjs.com/package/@augment-vir/node)
 */
export declare function grep<const CountOnly extends boolean = false>(grepSearchPattern: Readonly<GrepSearchPattern>, grepSearchLocation: Readonly<GrepSearchLocation>, options?: Readonly<GrepOptions<CountOnly>>): Promise<GrepMatches<CountOnly>>;
