use crate::sns::report::{
SNS_CANISTER_REPORT_SCHEMA_VERSION, SnsCanisterCycleBalanceStatus, SnsCanisterReport,
SnsCanisterSource, SnsHostError, SnsLookupRequest, live::LiveSnsSource,
lookup::resolve_sns_lookup, source::canonicalize_mainnet_sns_canister_inventory,
};
pub async fn build_sns_canister_report(
request: &SnsLookupRequest,
) -> Result<SnsCanisterReport, SnsHostError> {
build_sns_canister_report_with_source(request, &LiveSnsSource::default()).await
}
pub async fn build_sns_canister_report_with_source(
request: &SnsLookupRequest,
source: &dyn SnsCanisterSource,
) -> Result<SnsCanisterReport, SnsHostError> {
let lookup = resolve_sns_lookup(request, source).await?;
let mut inventory = source
.fetch_sns_canisters(&lookup.fetch_request, &lookup.sns)
.await?;
canonicalize_mainnet_sns_canister_inventory(&mut inventory)?;
let health_status_count = inventory
.canisters
.iter()
.filter(|canister| canister.status.is_some())
.count();
let reported_zero_cycles_count = inventory
.canisters
.iter()
.filter(|canister| {
canister.cycle_balance_status == SnsCanisterCycleBalanceStatus::ReportedZero
})
.count();
let cycles_unavailable_count = inventory
.canisters
.iter()
.filter(|canister| {
canister.cycle_balance_status == SnsCanisterCycleBalanceStatus::Unavailable
})
.count();
Ok(SnsCanisterReport {
schema_version: SNS_CANISTER_REPORT_SCHEMA_VERSION,
context: crate::sns::SnsInstanceContext::from_live(
lookup.fetch_request,
lookup.sns.id,
lookup.sns.name,
lookup.sns.canisters.root_canister_id,
),
canister_count: inventory.canisters.len(),
health_status_count,
reported_zero_cycles_count,
cycles_unavailable_count,
gap_count: inventory.gaps.len(),
inventory,
})
}