import { isMultiReference, isReference } from "../syntax-tree.js";
import { getDocument, streamAst, streamReferences } from "../utils/ast-utils.js";
import { toDocumentSegment } from "../utils/cst-utils.js";
import { cancellation_exports } from "../utils/cancellation.js";
import { interruptAndCheck } from "../utils/promise-utils.js";
import { UriUtils } from "../utils/uri-utils.js";
var DefaultAstNodeDescriptionProvider = class {
	constructor(e) {
		this.astNodeLocator = e.workspace.AstNodeLocator, this.nameProvider = e.references.NameProvider;
	}
	createDescription(e, t, r) {
		let i = r ?? getDocument(e);
		t ??= this.nameProvider.getName(e);
		let o = this.astNodeLocator.getAstNodePath(e);
		if (!t) throw Error(`Node at path ${o} has no name.`);
		let s, c = () => s ??= toDocumentSegment(this.nameProvider.getNameNode(e) ?? e.$cstNode);
		return {
			node: e,
			name: t,
			get nameSegment() {
				return c();
			},
			selectionSegment: toDocumentSegment(e.$cstNode),
			type: e.$type,
			documentUri: i.uri,
			path: o
		};
	}
}, DefaultReferenceDescriptionProvider = class {
	constructor(e) {
		this.nodeLocator = e.workspace.AstNodeLocator;
	}
	async createDescriptions(e, t = cancellation_exports.CancellationToken.None) {
		let n = [], a = e.parseResult.value;
		for (let e of streamAst(a)) await interruptAndCheck(t), streamReferences(e).forEach((e) => {
			e.reference.error || n.push(...this.createInfoDescriptions(e));
		});
		return n;
	}
	createInfoDescriptions(r) {
		let i = r.reference;
		if (i.error || !i.$refNode) return [];
		let o = [];
		isReference(i) && i.$nodeDescription ? o = [i.$nodeDescription] : isMultiReference(i) && (o = i.items.map((e) => e.$nodeDescription).filter((e) => e !== void 0));
		let s = getDocument(r.container).uri, l = this.nodeLocator.getAstNodePath(r.container), u = [], d = toDocumentSegment(i.$refNode);
		for (let e of o) u.push({
			sourceUri: s,
			sourcePath: l,
			targetUri: e.documentUri,
			targetPath: e.path,
			segment: d,
			local: UriUtils.equals(e.documentUri, s)
		});
		return u;
	}
};
export { DefaultAstNodeDescriptionProvider, DefaultReferenceDescriptionProvider };
