use indexmap::map::IndexMap as HashMap;
use indexmap::set::IndexSet as HashSet;
use autocxx_parser::IncludeCppConfig;
use crate::{
conversion::{api::Api, apivec::ApiVec},
types::QualifiedName,
};
use super::{deps::HasDependencies, fun::FnPhase};
pub(crate) fn filter_apis_by_following_edges_from_allowlist(
apis: ApiVec<FnPhase>,
config: &IncludeCppConfig,
) -> ApiVec<FnPhase> {
let mut todos: Vec<QualifiedName> = apis
.iter()
.filter(|api| {
let tnforal = api.name_for_allowlist();
config.is_on_allowlist(&tnforal.to_cpp_name())
})
.map(Api::name)
.cloned()
.collect();
let mut by_typename: HashMap<QualifiedName, ApiVec<FnPhase>> = HashMap::new();
for api in apis.into_iter() {
let tn = api.name().clone();
by_typename.entry(tn).or_default().push(api);
}
let mut done = HashSet::new();
let mut output = ApiVec::new();
while !todos.is_empty() {
let todo = todos.remove(0);
if done.contains(&todo) {
continue;
}
if let Some(mut these_apis) = by_typename.remove(&todo) {
todos.extend(these_apis.iter().flat_map(|api| api.deps().cloned()));
output.append(&mut these_apis);
} done.insert(todo);
}
output
}