use std::path::PathBuf;
use anyhow::Result;
use sdivi_config::Config;
use sdivi_core::compute::coupling::compute_coupling_topology;
use sdivi_core::compute::patterns::compute_pattern_metrics;
use sdivi_core::compute::thresholds::compute_thresholds_check;
use sdivi_core::input::{
DependencyGraphInput, EdgeInput, NodeInput, PatternInstanceInput, ThresholdsInput,
};
use sdivi_core::normalize_and_hash;
use sdivi_lang_rust::RustAdapter;
use sdivi_pipeline::{current_timestamp, Pipeline, WriteMode};
fn main() -> Result<()> {
let repo_root = std::env::args()
.nth(1)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("tests/fixtures/simple-rust"));
let config = Config::default();
let pipeline = Pipeline::new(config.clone(), vec![Box::new(RustAdapter)]);
let ts = current_timestamp();
let reference =
pipeline.snapshot_with_mode(&repo_root, None, &ts, WriteMode::EphemeralForCheck)?;
let nodes: Vec<NodeInput> = reference
.path_partition
.keys()
.map(|path| NodeInput {
id: path.clone(),
path: path.clone(),
language: "rust".to_string(),
})
.collect();
let node_ids: std::collections::BTreeMap<&str, usize> = nodes
.iter()
.enumerate()
.map(|(i, n)| (n.id.as_str(), i))
.collect();
let edges: Vec<EdgeInput> = {
let adapters: Vec<Box<dyn sdivi_parsing::adapter::LanguageAdapter>> =
vec![Box::new(RustAdapter)];
let records = sdivi_parsing::parse::parse_repository(&config, &repo_root, &adapters);
let mut result = Vec::new();
for record in &records {
let src = record.path.to_string_lossy().to_string();
if !node_ids.contains_key(src.as_str()) {
continue;
}
for import in &record.imports {
if node_ids.contains_key(import.as_str()) {
result.push(EdgeInput {
source: src.clone(),
target: import.clone(),
});
}
}
}
result
};
let graph_input = DependencyGraphInput { nodes, edges };
let coupling = compute_coupling_topology(&graph_input)?;
let fp = normalize_and_hash("function_item", &[]);
let patterns: Vec<PatternInstanceInput> = vec![PatternInstanceInput {
fingerprint: fp,
category: "functions".to_string(),
node_id: "src/lib.rs".to_string(),
location: None,
}];
let pattern_metrics = compute_pattern_metrics(&patterns);
use sdivi_core::null_summary;
let check = compute_thresholds_check(&null_summary(), &ThresholdsInput::default());
println!("=== embed_compute results ===");
println!("nodes (pure-compute): {}", coupling.node_count);
println!("edges (pure-compute): {}", coupling.edge_count);
println!(
"entropy (pure-compute):{:.4}",
pattern_metrics.total_entropy
);
println!("breached: {}", check.breached);
println!("\n=== parity check ===");
println!(
"pipeline nodes={} compute nodes={} — match={}",
reference.graph.node_count,
coupling.node_count,
reference.graph.node_count == coupling.node_count,
);
Ok(())
}