// Pure ranking function behind workspace search. Kept separate from the hook and
// component so the matching/ranking rules are exhaustively unit-testable in
// isolation (no React, no async).
//
// Match semantics intentionally mirror `internal/file-tree/filterFileTree` —
// case-insensitive substring — but widened from a node's basename to the full
// relative path, so `foo/bar` is findable and directory context is searchable
// (DD-10). The trivial predicate is not extracted into a shared micro-module; a
// cross-reference comment is the lower-coupling, honest choice.
/**
 * Ranks a flat listing against a query, returning matched files best-first.
 *
 * - Case-insensitive substring on the full relative path.
 * - Directories and advisory `notice` entries are never matched (a defensive
 *   guard even though the shared cache already strips notices — DD-11).
 * - Empty/whitespace query returns `[]` (search shows a hint, not everything).
 *
 * Ranking, in order: a basename hit outranks a path-only hit; then an earlier
 * match offset; then a shorter path; then lexicographic path for a stable,
 * deterministic order.
 */
export function matchWorkspaceFiles(files, query) {
    const trimmed = query.trim();
    if (trimmed.length === 0)
        return [];
    const needle = trimmed.toLowerCase();
    const ranked = [];
    for (const file of files) {
        if (file.isDirectory || file.notice)
            continue;
        const matchStart = file.path.toLowerCase().indexOf(needle);
        if (matchStart === -1)
            continue;
        const lastSlash = file.path.lastIndexOf("/");
        ranked.push({
            path: file.path,
            matchStart,
            matchEnd: matchStart + needle.length,
            isBasenameHit: matchStart >= lastSlash + 1,
        });
    }
    ranked.sort(compareMatches);
    return ranked.map(({ path, matchStart, matchEnd }) => ({
        path,
        matchStart,
        matchEnd,
    }));
}
function compareMatches(a, b) {
    if (a.isBasenameHit !== b.isBasenameHit)
        return a.isBasenameHit ? -1 : 1;
    if (a.matchStart !== b.matchStart)
        return a.matchStart - b.matchStart;
    if (a.path.length !== b.path.length)
        return a.path.length - b.path.length;
    return a.path.localeCompare(b.path);
}
//# sourceMappingURL=matchWorkspaceFiles.js.map