1use std::collections::BTreeMap;
2
3use crate::{Scanner, ScannerImpl};
4use chrono::DateTime;
5use luct_core::store::SearchableStoreRead;
6use serde::{Deserialize, Serialize};
7use web_time::{SystemTime, UNIX_EPOCH};
8
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct BasicStatistics {
11 roots_cas: Vec<(String, u64)>,
12 scts: Vec<(String, u64)>,
13}
14
15impl<S: ScannerImpl> Scanner<S> {
16 pub fn basic_statistics(&self) -> BasicStatistics {
17 let now = DateTime::from_timestamp_millis(
18 SystemTime::now()
19 .duration_since(UNIX_EPOCH)
20 .unwrap()
21 .as_millis() as i64,
22 )
23 .unwrap();
24
25 let reports = self.report_store.filter(|_, value| value.not_after > now);
26
27 let mut roots_cas = BTreeMap::new();
28 let mut scts = BTreeMap::new();
29
30 for (_, report) in reports.into_iter() {
31 roots_cas
32 .entry(report.ca_issuer)
33 .and_modify(|entry| *entry += 1)
34 .or_insert(1);
35
36 for sct in report.scts {
37 if let Some(name) = sct.log_name {
38 scts.entry(name)
39 .and_modify(|entry| *entry += 1)
40 .or_insert(1);
41 }
42 }
43 }
44
45 BasicStatistics {
46 roots_cas: roots_cas.into_iter().collect(),
47 scts: scts.into_iter().collect(),
48 }
49 }
50}