use crate::parser::slugify_page_name;
use std::collections::HashMap;
use super::PageStore;
pub fn build_link_indices(store: &mut PageStore) -> HashMap<String, String> {
let page_info: Vec<(String, Vec<String>, Vec<String>, Option<String>, Option<String>)> = store
.pages
.iter()
.map(|(id, page)| {
(
id.clone(),
page.outgoing_links.clone(),
page.meta.tags.clone(),
page.namespace.clone(),
page.subgraph.clone(),
)
})
.collect();
let mut original_names: HashMap<String, String> = HashMap::new();
for (id, _, _, _, _) in &page_info {
store.backlinks.entry(id.clone()).or_default();
}
for (id, outgoing, tags, namespace, subgraph) in &page_info {
let mut forward = Vec::new();
for link_name in outgoing {
let resolved =
resolve_link(link_name, namespace.as_deref(), subgraph.as_deref(), store);
if !store.pages.contains_key(&resolved) {
original_names
.entry(resolved.clone())
.or_insert_with(|| link_name.clone());
}
if !forward.contains(&resolved) {
forward.push(resolved.clone());
}
store
.backlinks
.entry(resolved)
.or_default()
.push(id.clone());
}
for tag in tags {
let resolved =
resolve_link(tag, namespace.as_deref(), subgraph.as_deref(), store);
if !store.pages.contains_key(&resolved) {
original_names
.entry(resolved.clone())
.or_insert_with(|| tag.clone());
}
if !forward.contains(&resolved) {
forward.push(resolved.clone());
}
store
.backlinks
.entry(resolved)
.or_default()
.push(id.clone());
}
store.forward_links.insert(id.clone(), forward);
}
for backlinks in store.backlinks.values_mut() {
backlinks.sort();
backlinks.dedup();
}
original_names
}
fn resolve_link(
name: &str,
source_namespace: Option<&str>,
source_subgraph: Option<&str>,
store: &PageStore,
) -> String {
let target_slug = slugify_page_name(name);
if store.pages.contains_key(&target_slug) {
return target_slug;
}
if let Some(canonical) = store.alias_map.get(&target_slug) {
return canonical.clone();
}
if let Some(ns) = source_namespace {
let ns_slug = slugify_page_name(&format!("{}/{}", ns, name));
if store.pages.contains_key(&ns_slug) {
return ns_slug;
}
}
if let Some(sg) = source_subgraph {
let sg_slug = slugify_page_name(&format!("{}/{}", sg, name));
if store.pages.contains_key(&sg_slug) {
return sg_slug;
}
}
target_slug
}