use chrono::{DateTime, Utc};
use oxidized_state::storage_traits::{ReleaseRegistry, RunId, RunLedger};
use crate::deploy_runner::DeployByDigestRunner;
use crate::domain::{AivcsError, Result};
use crate::replay::{replay_run, ReplaySummary};
#[derive(Debug, Clone)]
pub struct DeployResult {
pub run_id: RunId,
pub spec_digest: String,
pub summary: ReplaySummary,
}
pub async fn deploy_by_digest(
registry: &dyn ReleaseRegistry,
ledger: &dyn RunLedger,
agent_name: &str,
timestamp: Option<DateTime<Utc>>,
) -> Result<DeployResult> {
let release = registry
.current(agent_name)
.await
.map_err(|e| AivcsError::StorageError(e.to_string()))?
.ok_or_else(|| {
AivcsError::ReleaseConflict(format!("no current release for agent '{}'", agent_name))
})?;
let spec_digest_str = release.spec_digest.as_str().to_string();
let output = match timestamp {
Some(ts) => {
DeployByDigestRunner::run_at(ledger, &release.spec_digest, agent_name, ts).await?
}
None => DeployByDigestRunner::run(ledger, &release.spec_digest, agent_name).await?,
};
let (_events, replay_summary) = replay_run(ledger, &output.run_id.0).await?;
Ok(DeployResult {
run_id: output.run_id,
spec_digest: spec_digest_str,
summary: replay_summary,
})
}