use super::state::{
AgentPhase, DeliveryPhase, Observation, RecoveryPhase, ResourcePhase, TaskState,
};
use crate::event::Lifecycle;
pub fn project(
agent: AgentPhase,
delivery: DeliveryPhase,
_resource: ResourcePhase,
recovery: RecoveryPhase,
task_state: TaskState,
) -> Lifecycle {
if agent == AgentPhase::Gone {
return Lifecycle::Exited;
}
if task_state == TaskState::Done && delivery == DeliveryPhase::Accepted {
return Lifecycle::Exited;
}
match task_state {
TaskState::Done | TaskState::Failed | TaskState::Cancelled | TaskState::Blocked => {
return Lifecycle::Working;
}
TaskState::Pending => {}
}
match delivery {
DeliveryPhase::Pending | DeliveryPhase::Retrying | DeliveryPhase::Exhausted => {
return Lifecycle::Working;
}
DeliveryPhase::NoIntent | DeliveryPhase::Accepted => {}
}
if recovery == RecoveryPhase::Draining {
return Lifecycle::Working;
}
match agent {
AgentPhase::Running => Lifecycle::Working,
AgentPhase::Idle | AgentPhase::Ready => match recovery {
RecoveryPhase::IdleWaiting | RecoveryPhase::IdleFault => Lifecycle::Working,
_ => Lifecycle::Idle,
},
AgentPhase::Booting | AgentPhase::Gone => Lifecycle::Created,
}
}
#[allow(clippy::collapsible_if)]
pub fn is_legal(obs: &Observation) -> bool {
if obs.isolate_after == 0 || obs.terminate_after == 0 {
return false;
}
if !obs.generation_live && obs.recovery != RecoveryPhase::NoRecovery {
return false;
}
if obs.agent == AgentPhase::Gone {
if obs.recovery != RecoveryPhase::NoRecovery {
return false;
}
}
match obs.recovery {
RecoveryPhase::IdleWaiting | RecoveryPhase::IdleFault => {
if obs.agent != AgentPhase::Idle {
return false;
}
}
RecoveryPhase::Draining => {
if obs.agent != AgentPhase::Idle && obs.agent != AgentPhase::Running {
return false;
}
}
RecoveryPhase::NoRecovery => {}
}
if obs.delivery == DeliveryPhase::Accepted && matches!(obs.agent, AgentPhase::Booting) {
return false;
}
if obs.delivery == DeliveryPhase::Exhausted && obs.agent == AgentPhase::Ready {
return false;
}
true
}