function dedupe(values) {
    return [...new Set(values.filter((value) => value.length > 0))];
}
function stripCollisionSuffix(value) {
    const hashIndex = value.indexOf("#");
    return hashIndex >= 0 ? value.slice(0, hashIndex) : value;
}
function stripDisplayKindSuffix(value) {
    return value.replace(/\s+\([^()]+\)$/, "");
}
export function getGraphNodeId(node, fallbackId = "") {
    return node.qualifiedName || node.id || fallbackId || node.name || "";
}
export function getGraphNodeLabel(node, fallbackId = "") {
    const label = node.name?.trim();
    if (label && label.length > 0) {
        return label;
    }
    const id = getGraphNodeId(node, fallbackId);
    return id.split(".").pop() || id;
}
export function getGraphNodeAliases(node, fallbackId = "") {
    const id = getGraphNodeId(node, fallbackId);
    const label = getGraphNodeLabel(node, fallbackId);
    const shortId = id.split(".").pop() || id;
    return dedupe([
        id,
        node.id ?? "",
        node.qualifiedName ?? "",
        label,
        stripDisplayKindSuffix(label),
        shortId,
        stripCollisionSuffix(shortId),
        stripCollisionSuffix(id),
    ]);
}
function compareLabels(a, b) {
    return a.localeCompare(b, undefined, { sensitivity: "base" });
}
export function compareGraphNodeIds(a, b, nodes) {
    const nodeA = nodes.get(a);
    const nodeB = nodes.get(b);
    const exportedA = nodeA ? Number(!!nodeA.exported) : 0;
    const exportedB = nodeB ? Number(!!nodeB.exported) : 0;
    if (exportedA !== exportedB) {
        return exportedB - exportedA;
    }
    const labelA = getGraphNodeLabel(nodeA ?? {}, a);
    const labelB = getGraphNodeLabel(nodeB ?? {}, b);
    const labelComparison = compareLabels(labelA, labelB);
    if (labelComparison !== 0) {
        return labelComparison;
    }
    return compareLabels(a, b);
}
export function matchesGraphNodeQuery(query, node, fallbackId = "") {
    const normalizedQuery = query.trim().toLowerCase();
    if (normalizedQuery.length === 0) {
        return false;
    }
    return getGraphNodeAliases(node, fallbackId).some((alias) => alias.toLowerCase().includes(normalizedQuery));
}
export function resolveGraphNodeIds(nodes, symbolName) {
    const query = symbolName.trim();
    if (query.length === 0) {
        return [];
    }
    if (nodes.has(query)) {
        return [query];
    }
    const exactMatches = [...nodes.entries()]
        .filter(([id, node]) => getGraphNodeAliases(node, id).includes(query))
        .map(([id]) => id)
        .sort((a, b) => compareGraphNodeIds(a, b, nodes));
    if (exactMatches.length > 0) {
        return exactMatches;
    }
    return [...nodes.entries()]
        .filter(([id, node]) => matchesGraphNodeQuery(query, node, id))
        .map(([id]) => id)
        .sort((a, b) => compareGraphNodeIds(a, b, nodes));
}
