import { IOResult, type ByteSource } from '../../../io/types.ts';
import { FileType, LineFacts, PathSpec, type CopyDeref, type CopyStrategy, type FileStat, type NativeMove, type PrimitiveCopy, type PrimitiveMove, type ReaddirFn, type StatFn } from '../../../types.ts';
import type { FlagView } from '../../spec/flag_view.ts';
import { type BackendKeyFn } from '../utils/copy.ts';
import type { LinkView } from '../../../view/types.ts';
import type { DispatchFn } from '../../../runtime/types.ts';
import type { FsCondition } from '../../../errors/types.ts';
export interface CpFlags {
    recursive: boolean;
    noClobber: boolean;
    interactive: boolean;
    verbose: boolean;
    update: string | null;
    backup: string | null;
    suffix: string;
    targetDir: PathSpec | null;
    noTargetDir: boolean;
    dereference: CopyDeref;
}
/**
 * Namespace symlink facts and dispatcher primitives for cp and mv.
 * Links live above every backend, so no copy strategy lists one and a tree
 * copy has to recreate each by name. `relay` and `relayStat` are the dispatcher's
 * own transfer primitives, which copy what a followed link leads to on
 * whatever mount it lives. Mirrors Python's TransferLinks.
 */
export interface TransferLinks {
    links: LinkView;
    dispatch: DispatchFn;
    cwd: string;
    relay: PrimitiveCopy;
    relayStat: StatFn;
    /** Whether the mount the copy runs on serves a path; absent where every path
     * is its own. */
    owns?: (virtual: string) => boolean;
}
export declare function cpFlags(init?: Partial<CpFlags>): CpFlags;
export interface TransferPolicy {
    cmdName: string;
    noClobber: boolean;
    update: string | null;
    backup: string | null;
    suffix: string;
    ask?: ((target: PathSpec) => Promise<boolean>) | null;
}
/**
 * GNU's -i: ask on stderr before replacing a target and read one line of
 * stdin as the answer. Only a line starting with `y` or `Y` is yes (rpmatch
 * in the C locale); the end of input is no. A yes is recorded in `accepted`,
 * since it is no failure. Mirrors Python's prompter.
 */
export declare function prompter(cmdName: string, stdin: ByteSource | null, errors: string[], accepted: string[]): (target: PathSpec) => Promise<boolean>;
export declare function stderrOf(errors: readonly string[]): Uint8Array | null;
export declare function updateGates(mode: string | null): boolean;
export declare function backupDisplaces(control: string | null): boolean;
export declare function updateMode(cmdName: string, fl: FlagView): string | null;
export declare function suffixFlag(fl: FlagView): string | null;
export declare function backupRaw(fl: FlagView): string | boolean | undefined;
export declare function targetFlags(cmdName: string, fl: FlagView): [PathSpec | null, boolean];
export declare function parseFlags(fl: FlagView): CpFlags;
/** Stat the entry itself for overwrite and backup decisions. */
export declare function linkStat(copies: TransferLinks, path: PathSpec): Promise<FileStat>;
export declare function renameLink(copies: TransferLinks, src: PathSpec, target: PathSpec): Promise<void>;
/**
 * stat(2) of a destination, over a table whose stat is lstat(2). cp opens its
 * destination the way open(2) does, through a link at the name: a link to a
 * directory is that directory, one to a file is the file it writes through, and
 * one that leads nowhere is no destination at all (cp then refuses to write
 * through it). Mirrors Python's dest_stat.
 */
export declare function destStat(stat: StatFn, copies: TransferLinks | undefined): StatFn;
/**
 * The destination as the link standing at its name, null where none does. The
 * router follows a destination to what its link leads to, which is what a plain
 * copy writes, through the link. GNU's backup renames the destination itself, a
 * link included, and the copy then lands at the name, so a backup is made of
 * this and the copy goes here: through the mount's own copy, which keeps the
 * source's mode, or through the dispatcher where the name sits on another mount
 * (`owns`). Mirrors Python's link_name.
 */
export declare function linkName(copies: TransferLinks, target: PathSpec): PathSpec | null;
/** Copy a symlink through the shared overwrite and backup policy. */
export declare function makeLink(copies: TransferLinks, src: PathSpec, target: PathSpec, text: string, policy: TransferPolicy, errors: string[], lines: string[] | undefined): Promise<boolean>;
/**
 * Recreate the links below a copied directory, which its copy could not see.
 * Without -L each lands as a link with its target verbatim, dangling and
 * looping ones included. Under -L each is what it leads to: a file's bytes, a
 * directory's whole tree (the links below it included), and `cannot stat` for
 * one that leads nowhere or loops (coreutils 9.7). A link that leads back into
 * a tree being copied is refused as GNU names it, `cannot copy cyclic symbolic
 * link`, rather than copied until the name is too long, which is where GNU
 * stops. Mirrors Python's copy_tree_links.
 */
export declare function copyTreeLinks(copies: TransferLinks, deref: CopyDeref, src: PathSpec, target: PathSpec, errors: string[], lines: string[] | undefined, policy: TransferPolicy, seen?: readonly string[], blocked?: readonly string[]): Promise<void>;
export declare function splitOperands(cmdName: string, paths: PathSpec[], targetDir: PathSpec | null, noTargetDir: boolean): [PathSpec[], PathSpec];
export declare function targetDirError(cmdName: string, stat: StatFn, target: PathSpec): Promise<string | null>;
export declare function destKind(stat: StatFn, target: PathSpec): Promise<{
    exists: boolean;
    isDir: boolean;
    condition: FsCondition | null;
}>;
export declare function slashRefusesFile(target: PathSpec, targetExists: boolean, srcIsDir: boolean): boolean;
export declare function sourceKind(stat: StatFn, path: PathSpec): Promise<{
    kind: FileType | null;
    condition: FsCondition | null;
}>;
export declare function overwriteTypeError(cmdName: string, src: PathSpec, srcIsDir: boolean, target: PathSpec, targetExists: boolean, targetIsDir: boolean): string | null;
export declare function typeMismatchError(cmdName: string, src: PathSpec, target: PathSpec, srcIsDir: boolean): string;
export declare function sameFileError(cmdName: string, src: PathSpec, target: PathSpec): string;
export declare function justCreatedError(cmdName: string, src: PathSpec, target: PathSpec): string;
export declare function overwriteGate(policy: TransferPolicy, stat: StatFn, src: PathSpec, target: PathSpec, errors: string[], copies?: TransferLinks): Promise<boolean>;
export declare function makeBackup(policy: TransferPolicy, strategy: CopyStrategy | PrimitiveMove | NativeMove, stat: StatFn, readdir: ReaddirFn | undefined, target: PathSpec, errors: string[], copies?: TransferLinks): Promise<{
    backup: PathSpec | null;
    ok: boolean;
}>;
export declare function within(path: string, root: string): boolean;
export declare function walk(readdir: ReaddirFn, stat: StatFn, root: PathSpec, cmdName?: string, errors?: string[], links?: LinkView): Promise<{
    path: string;
    kind: FileType;
}[]>;
export declare function copyEntries(cmdName: string, strategy: PrimitiveCopy | PrimitiveMove, stat: StatFn, src: PathSpec, target: PathSpec, entries: {
    path: string;
    kind: FileType;
}[], errors: string[], opts?: {
    policy?: TransferPolicy;
    lines?: string[] | undefined;
    copies?: TransferLinks | undefined;
    rootBackup?: PathSpec | null;
    blocked?: string[];
}): Promise<boolean>;
/**
 * Copy one file between the strategy's mounts, reporting a failure in GNU's
 * words; false when it failed. A store-to-store copy goes first where the
 * strategy has one: the destination's store copies from the source's without
 * the bytes passing through mirage. EXDEV from it says the stores cannot, as
 * ENOTSUP does from a store with no copy of its own, and a declined walk says
 * a hide or rule wants the copy made by parts; either way
 * the bytes move through a read and a write, the file materialized in
 * between. Mirrors Python's transfer_file.
 */
export declare function transferFile(strategy: PrimitiveCopy | PrimitiveMove, src: PathSpec, dst: PathSpec, cmdName: string, errors: string[]): Promise<boolean>;
export declare function cpGeneric(paths: PathSpec[], stat: StatFn, strategy: CopyStrategy, flags: CpFlags, backendKey?: BackendKeyFn, readdir?: ReaddirFn, linkAt?: (path: PathSpec) => FileStat | null, copies?: TransferLinks, stdin?: ByteSource | null, dispatch?: DispatchFn): Promise<[ByteSource | null, IOResult]>;
/**
 * A cp line reads below its sources when it copies recursively (`-r`, `-R`,
 * `-a`), and copies into the directory `-t` names if it names one. Mirrors
 * Python's `facts`.
 */
export declare function facts(fl: FlagView, _operands: readonly (string | PathSpec)[]): LineFacts;
//# sourceMappingURL=cp.d.ts.map