use std::collections::{HashMap, HashSet};
use crate::{
api::ApiClient,
types::{Diagnostic, InstalledComponent, StoreEntry, UpdateCheckResult},
};
use super::{IdLookup, evaluation, resolution};
pub(crate) fn check_components(
registry_components: &[InstalledComponent],
client: &ApiClient,
store_entries: &[StoreEntry],
lookup: &IdLookup,
result: &mut UpdateCheckResult,
) {
let resolved: Vec<(&InstalledComponent, u64)> = registry_components
.iter()
.filter_map(|c| resolution::resolve_content_id(c, store_entries, lookup).map(|id| (c, id)))
.collect();
let missing_ids: Vec<u64> = {
let mut seen = HashSet::new();
resolved
.iter()
.filter(|(_, id)| resolution::find_store_entry(store_entries, *id).is_none())
.filter(|(_, id)| seen.insert(*id))
.map(|(_, id)| *id)
.collect()
};
let fetched: HashMap<u64, StoreEntry> = client
.fetch_details(&missing_ids)
.into_iter()
.zip(missing_ids.iter())
.filter_map(|(r, &id)| match r {
Ok(e) => Some((id, e)),
Err(e) => {
log::warn!(
target: "resolver",
"failed to fetch store entry {}: {}",
id,
e
);
None
}
})
.collect();
for (component, content_id) in &resolved {
let entry = resolution::find_store_entry(store_entries, *content_id)
.or_else(|| fetched.get(content_id));
match entry {
Some(entry) => match evaluation::evaluate_store_entry(component, entry, *content_id) {
evaluation::ComponentCheckResult::Update(update) => {
result.add_update(*update);
}
evaluation::ComponentCheckResult::CheckFailed(diagnostic) => {
result.add_check_failure(diagnostic);
}
evaluation::ComponentCheckResult::UpToDate => {}
evaluation::ComponentCheckResult::Unresolved(_) => {
unreachable!("evaluate_store_entry never returns Unresolved")
}
},
None => {
let diagnostic = Diagnostic::new(
component.name.clone(),
"failed to fetch store entry".to_string(),
)
.with_content_id(*content_id);
result.add_check_failure(diagnostic);
}
}
}
for component in registry_components {
if !resolved
.iter()
.any(|(c, _)| c.directory_name == component.directory_name)
{
let diagnostic = Diagnostic::new(
component.name.clone(),
"could not match to kde store entry".to_string(),
);
result.add_unresolved(diagnostic);
}
}
}