import type { Context } from '../../config.ts';
import type { FollowOperands, LinkView, MountView } from '../../../view/types.ts';
import type { DispatchFn } from '../../../runtime/types.ts';
import type { FileStat, Limit } from '../../../types.ts';
import { PathSpec } from '../../../types.ts';
import type { ByteSource } from '../../../io/types.ts';
import { type Files } from '../../../workspace/files.ts';
/**
 * Where a name stands as lstat reaches it: every link above its final name
 * followed, the name itself kept.
 *
 * The walk the kernel gives a path before a call that does not follow its
 * final name, and the key the table files a link under, since every link is
 * keyed by its resolved parent. A path ending in a slash resolves whole:
 * POSIX reads `dlink/` as `dlink/.`. Throws CycleError on a loop. Mirrors
 * Python's link_location.
 */
export declare function linkLocation(links: LinkView, virtual: string): string;
/**
 * Where the name an operand was typed as stands, as lstat reaches it.
 *
 * Every component but the last resolves through the links, as the kernel
 * walks any path, so `dl/tl.gz` with `dl` a link to `dir` stands at
 * `dir/tl.gz`: the table keys every link by that resolved parent. Null where
 * the last component resolves as well, which is a name typed with a trailing
 * slash or ending in a dot, and where the walk already failed. Mirrors
 * Python's name_location.
 */
export declare function nameLocation(links: LinkView, path: PathSpec, cwd: string): string | null;
/**
 * The link standing at the name an operand was typed as, its own row.
 *
 * The router follows an operand through its link before the command runs,
 * which leaves `virtual` at the target and the name in `rawPath`; a command
 * that acts on the name itself (cp -P, gzip's O_NOFOLLOW open) asks here.
 * Null where no link stands at the name. Mirrors Python's typed_link.
 */
export declare function typedLink(links: LinkView, path: PathSpec, cwd: string): FileStat | null;
/**
 * The namespace's links as a command meets a name, and the dispatcher past them.
 *
 * A link is invisible to every backend, so a command bound to one mount needs
 * the links to tell a name that stands on one, and the dispatcher to act where
 * the link leads or where it stands: the target may live on any mount, and so
 * may the link. Mirrors Python's LinkResolver.
 */
export declare class LinkResolver {
    readonly links: LinkView;
    readonly dispatch: DispatchFn;
    readonly cwd: string;
    constructor(links: LinkView, dispatch: DispatchFn, cwd: string);
    /** Where the link standing at an operand's name sits, null where no link
     * stands there. */
    linkAt(path: PathSpec): string | null;
    /**
     * Whether the link the router followed an operand through is gone.
     *
     * The router follows every operand before the command runs, so an earlier
     * operand that removed the link (`gunzip -f l.gz l.gz`) leaves a later one
     * at the old target: GNU opens each name when it reaches it, and finds
     * nothing there.
     */
    vanished(path: PathSpec): boolean;
    /**
     * Where a link leads, every link on the way followed. A chain that loops
     * throws ELOOP, an error a walker reports as it reports any failed stat.
     */
    target(link: string): string;
    /** What a name leads to, its stat through the dispatcher, on any mount. */
    stat(virtual: string): Promise<FileStat>;
    /** A directory's entries through the dispatcher, links among them. */
    readdir(virtual: string): Promise<string[]>;
    /** A name's own stat through the dispatcher: a link's, not its target's. */
    lstat(path: PathSpec): Promise<FileStat>;
    /** What a name leads to, read through the dispatcher, which follows it. */
    read(virtual: string): AsyncIterable<Uint8Array>;
    /** Write a file on the mount that owns the name. */
    write(virtual: string, data: ByteSource): Promise<void>;
    /** Remove the name itself, a link rather than what it leads to. */
    unlink(virtual: string): Promise<void>;
}
/** Whether the mount at `prefix` is the one serving `virtual`; every path is
 * where no mount table says otherwise. Mirrors Python's serves. */
export declare function serves(mounts: MountView | undefined, prefix: string, virtual: string): boolean;
/**
 * The mount a walked path lands on, every link on it followed. A mount is
 * mirage's filesystem, so this stands for the device stat(2) reports, which
 * `find -xdev` compares with the start point's: a link onto another mount
 * leaves it as a mount root does (findutils 4.10). `virtual` is a directory
 * the walk reached, which resolves. Mirrors Python's landing_root.
 */
export declare function landingRoot(mounts: MountView, links: LinkView | null, virtual: string): string;
/**
 * The symlink facts a walk goes by, read off the session's files, or
 * undefined outside a workspace.
 *
 * The dispatcher's reader answers (`NamespaceReader`), filtered by the rule
 * it refuses a call by: a hidden link, or one that leads where the session
 * cannot see, has no row, no listing entry and no target. Resolving a hidden
 * path leaves it as typed, for the dispatcher to refuse; a visible one
 * resolves, so a walker judges where it lands. Mirrors Python's link_view.
 */
export declare function linkView(files: Files | undefined): LinkView | undefined;
/**
 * Where the mount boundaries are, read off the session's files, or undefined
 * outside a workspace. Every mount below a path, hidden or not, is a boundary
 * a backend's own walk stops at; only the visible ones are ever named. A walk
 * through the dispatcher (`crossing`) has no boundary to stop at
 * (`NamespaceReader.mounts`). Mirrors Python's mount_view.
 */
export declare function mountView(files: Files | undefined, crossing?: boolean, command?: string | null, profile?: Readonly<Record<string, Limit>>): MountView | undefined;
/**
 * The names a directory holds only as namespace structure, as the session
 * sees them: the mounts below it and its links, each by its first segment
 * under the directory.
 *
 * No backend can list either, and the first may be one no backend serves at
 * all (a link made below a directory chain that holds no key); these are the
 * names the dispatcher merges into its own listing, from the same tables.
 * Mirrors Python's owed_names.
 */
export declare function owedNames(files: Files | undefined, directory: string): string[];
/** The workspace's links as the command's session sees them, read off its
 * files; undefined outside a workspace. Mirrors Python's links_of. */
export declare function linksOf(ctx: Context): LinkView | undefined;
/**
 * Whether the command walks across mounts: it runs on the session's files
 * with no mount's command scope bound, as a cross-mount run does, so every
 * call it makes reaches whichever mount serves the path. Mirrors Python's
 * crosses_mounts.
 */
export declare function crossesMounts(ctx: Context): boolean;
/**
 * The prefix of the mount the command runs on, without its trailing slash:
 * what a path the command makes up (an output name, a file a list names) is
 * keyed below. '' for a run across mounts, which keys every path by its
 * whole virtual path, and outside a workspace. Mirrors Python's mount_root.
 */
export declare function mountRoot(ctx: Context): string;
/**
 * Where the mount boundaries are for the command's walk, read off its files;
 * undefined outside a workspace. A run across mounts (`crossesMounts`) has
 * the dispatcher descend into every mount, so it has no boundary to stop at.
 * Mirrors Python's mounts_of.
 */
export declare function mountsOf(ctx: Context): MountView | undefined;
/** The link resolver an invocation carries: null outside a workspace.
 * Mirrors Python's link_resolver. */
export declare function linkResolver(ctx: Context): LinkResolver | null;
/** The dispatcher a command's files run on. Mirrors Python's dispatch_of. */
export declare function dispatchOf(ctx: Context): DispatchFn | undefined;
/** The line's operand resolution its files carry. Mirrors Python's follow_of. */
export declare function followOf(ctx: Context): FollowOperands | undefined;
//# sourceMappingURL=links.d.ts.map