use std::collections::{BTreeMap, BTreeSet, HashMap};
use super::types::RawEntity;
pub(super) fn reverse_aliases(aliases: &HashMap<String, String>) -> BTreeMap<String, Vec<String>> {
let mut reverse = BTreeMap::new();
for (alias, canonical) in aliases {
if alias == canonical {
continue;
}
reverse
.entry(canonical.clone())
.or_insert_with(Vec::new)
.push(alias.clone());
}
for values in reverse.values_mut() {
values.sort();
values.dedup();
}
reverse
}
pub(super) fn build_alias_map(entities: &HashMap<String, RawEntity>) -> HashMap<String, String> {
let mut by_type = HashMap::<String, Vec<String>>::new();
for entity in entities.values() {
by_type
.entry(entity.entity_type.clone())
.or_default()
.push(entity.name.clone());
}
let mut aliases = HashMap::new();
for names in by_type.values_mut() {
names.sort_by_key(|name| std::cmp::Reverse(name.len()));
for short in names.iter() {
for long in names.iter() {
if short == long || long.len() <= short.len() {
continue;
}
if long.starts_with(&format!("{short} ")) || long.ends_with(&format!(" {short}")) {
aliases.entry(short.clone()).or_insert_with(|| long.clone());
break;
}
}
}
}
aliases
}
pub(super) fn resolve_alias(name: &str, aliases: &HashMap<String, String>) -> String {
let mut current = name.to_string();
let mut seen = BTreeSet::new();
while let Some(next) = aliases.get(¤t) {
if !seen.insert(current.clone()) {
break;
}
current = next.clone();
}
current
}