use std::collections::HashMap;
use std::sync::Mutex;
use crate::runtime_types::{AnalysisReadiness, RecentPreflight};
use serde_json::Value;
pub(crate) struct RecentPreflightStore {
entries: Mutex<HashMap<String, RecentPreflight>>,
}
impl RecentPreflightStore {
pub fn new() -> Self {
Self {
entries: Mutex::new(HashMap::new()),
}
}
pub fn key(project_scope: &str, logical_session: &str) -> String {
format!("{project_scope}::{logical_session}")
}
#[allow(clippy::too_many_arguments)]
pub fn record_from_payload(
&self,
key: String,
tool_name: &str,
surface: &str,
now_ms: u64,
target_paths: Vec<String>,
symbol: Option<String>,
payload: &Value,
) {
let readiness = payload
.get("readiness")
.cloned()
.and_then(|value| serde_json::from_value::<AnalysisReadiness>(value).ok())
.unwrap_or_default();
let blocker_count = payload
.get("blocker_count")
.and_then(|value| value.as_u64())
.map(|value| value as usize)
.unwrap_or_else(|| {
payload
.get("blockers")
.and_then(|value| value.as_array())
.map(|value| value.len())
.unwrap_or_default()
});
let preflight = RecentPreflight {
tool_name: tool_name.to_owned(),
analysis_id: payload
.get("analysis_id")
.and_then(|value| value.as_str())
.map(ToOwned::to_owned),
surface: surface.to_owned(),
timestamp_ms: now_ms,
readiness,
blocker_count,
target_paths,
symbol,
};
self.entries
.lock()
.unwrap_or_else(|p| p.into_inner())
.insert(key, preflight);
}
pub fn get(&self, key: &str) -> Option<RecentPreflight> {
self.entries
.lock()
.unwrap_or_else(|p| p.into_inner())
.get(key)
.cloned()
}
pub fn clear(&self) {
self.entries
.lock()
.unwrap_or_else(|p| p.into_inner())
.clear();
}
#[cfg(test)]
pub fn set_timestamp_for_test(&self, key: &str, timestamp_ms: u64) {
if let Some(preflight) = self
.entries
.lock()
.unwrap_or_else(|p| p.into_inner())
.get_mut(key)
{
preflight.timestamp_ms = timestamp_ms;
}
}
}