use super::types::{ContextRelationship, FileRange, RelatedContext};
use crate::priority::call_graph::{CallGraph, FunctionId};
use std::collections::HashSet;
use std::path::Path;
pub fn extract_caller_contexts(
scope: &[FunctionId],
primary_file: &Path,
call_graph: &CallGraph,
max_callers: u32,
) -> Vec<RelatedContext> {
let scope_set: HashSet<&FunctionId> = scope.iter().collect();
let mut external_callers: Vec<FunctionId> = scope
.iter()
.flat_map(|fid| call_graph.get_callers(fid))
.filter(|caller| !scope_set.contains(caller))
.collect();
external_callers.sort();
external_callers.dedup();
external_callers.sort_by_key(|caller_id| {
if caller_id.file == primary_file {
0
} else if is_same_module(&caller_id.file, primary_file) {
1
} else {
2
}
});
external_callers
.into_iter()
.take(max_callers as usize)
.map(|caller| create_caller_context(&caller))
.collect()
}
fn is_same_module(file1: &Path, file2: &Path) -> bool {
file1.parent() == file2.parent()
}
fn create_caller_context(caller_id: &FunctionId) -> RelatedContext {
let reason = format!("Called by {}", caller_id.name);
let start_line = caller_id.line.saturating_sub(2);
let end_line = caller_id.line + 20;
RelatedContext {
range: FileRange {
file: caller_id.file.clone(),
start_line: start_line as u32,
end_line: end_line as u32,
symbol: Some(caller_id.name.clone()),
},
relationship: ContextRelationship::Caller,
reason,
}
}