use std::collections::BTreeSet;
use super::Finding;
use super::export::Export;
use super::tree::NodeIds;
use crate::bindings::{Bindings, Counters};
use crate::document::Edge;
use crate::ids::ElementId;
use crate::prose::{heading_lines, label_references};
pub(super) fn mentions(
export: &Export,
nodes: &NodeIds,
bindings: &Bindings,
) -> (Vec<Edge>, Vec<Finding>) {
let mut edges = Vec::new();
let mut findings = Vec::new();
let allocated = Counters::above(bindings);
for v1 in &export.nodes {
let Some(node) = nodes.get(&v1.node_id).copied() else {
continue;
};
let source = ElementId::from(node);
let body = v1.body.as_deref().unwrap_or("");
let mut targets = BTreeSet::new();
for reference in label_references(&v1.name)
.into_iter()
.chain(label_references(body))
.filter(|reference| allocated.has_allocated(*reference))
{
match bindings.resolve(reference) {
Some(target) if targets.insert(target) => {
edges.push(Edge::Mentions { source, target });
}
Some(_) => {}
None => findings.push(Finding::UnresolvedReference { node, reference }),
}
}
findings.extend(
heading_lines(body)
.into_iter()
.map(|line| Finding::HeadingInBody { node, line }),
);
}
(edges, findings)
}