use anyhow::Result;
use super::observer::Observer;
use super::types::CycleRecord;
use super::versioning::VersionControl;
pub struct EvolutionHistory {
observer: Observer,
versioning: VersionControl,
cycle_records: Vec<CycleRecord>,
}
impl EvolutionHistory {
pub fn new(observer: Observer, versioning: VersionControl) -> Self {
Self {
observer,
versioning,
cycle_records: Vec::new(),
}
}
pub fn record_cycle(&mut self, record: CycleRecord) {
self.cycle_records.push(record);
}
pub fn cycles(&self) -> &[CycleRecord] {
&self.cycle_records
}
pub fn latest_cycle(&self) -> u32 {
self.cycle_records.last().map(|r| r.cycle).unwrap_or(0)
}
pub fn get_observations(
&self,
last_n_cycles: usize,
only_failures: bool,
) -> Result<Vec<serde_json::Value>> {
let mut records = self.observer.get_recent_logs(last_n_cycles)?;
if only_failures {
records.retain(|r| !r.get("success").and_then(|v| v.as_bool()).unwrap_or(false));
}
Ok(records)
}
pub fn get_summary_stats(&self) -> Result<serde_json::Value> {
self.observer.get_summary_stats()
}
pub fn get_score_curve(&self) -> Vec<f64> {
self.cycle_records.iter().map(|r| r.score).collect()
}
pub fn get_workspace_diff(&self, from_label: &str, to_label: &str) -> Result<String> {
self.versioning.get_diff(from_label, to_label)
}
pub fn read_file_at(&self, version_label: &str, path: &str) -> Result<String> {
self.versioning.show_file_at(version_label, path)
}
pub fn list_versions(&self) -> Result<Vec<String>> {
self.versioning.list_tags()
}
pub fn get_version_log(&self, n: usize) -> Result<String> {
self.versioning.get_log(n)
}
pub fn observer_mut(&mut self) -> &mut Observer {
&mut self.observer
}
pub fn versioning(&self) -> &VersionControl {
&self.versioning
}
}