use time::OffsetDateTime;
use crate::entities::ceremony_events::{
EvidenceCollected, InterventionClosed, InterventionRequested, InterventionResponded,
};
use crate::entities::{CeremonyInstance, CeremonyIntervention};
use crate::value_objects::{
CeremonyInterventionId, CeremonyReason, CeremonyReasonKind, CeremonyRecordRef, MemoryConfidence,
};
impl CeremonyInstance {
pub(super) fn apply_intervention_requested(&mut self, requested: &InterventionRequested) {
self.updated_at = requested.intervention.created_at();
self.interventions.push(requested.intervention.clone());
}
pub(super) fn apply_intervention_responded(&mut self, responded: &InterventionResponded) {
let response = &responded.response;
let Some(intervention) = self.intervention_mut(&responded.intervention_id) else {
return;
};
let appended = match response.evidence_pack() {
Some(evidence_pack) => intervention.respond_with_evidence(
response.role_id().clone(),
evidence_pack.clone(),
response.responded_at(),
),
None => intervention.respond(
response.role_id().clone(),
response.content().clone(),
response.responded_at(),
),
};
if appended.is_ok() {
self.record_that_it_answers(&responded.intervention_id, response.responded_at());
}
self.updated_at = response.responded_at();
}
pub(super) fn apply_intervention_closed(&mut self, closed: &InterventionClosed) {
if let Some(intervention) = self.intervention_mut(&closed.intervention_id) {
let _closed = intervention.close(&closed.closed_by, closed.closed_at);
}
self.updated_at = closed.closed_at;
}
pub(super) fn apply_evidence_collected(&mut self, collected: &EvidenceCollected) {
self.updated_at = collected.collected_at;
}
fn intervention_mut(
&mut self,
intervention_id: &CeremonyInterventionId,
) -> Option<&mut CeremonyIntervention> {
self.interventions
.iter_mut()
.find(|intervention| intervention.id() == intervention_id)
}
fn record_that_it_answers(
&mut self,
agenda_item: &CeremonyInterventionId,
now: OffsetDateTime,
) {
let Some(ordinal) = self
.intervention(agenda_item)
.map(|item| item.responses().len())
.and_then(|count| u32::try_from(count.checked_sub(1)?).ok())
else {
return;
};
if let Ok(reason) = CeremonyReason::new(
CeremonyRecordRef::contribution(agenda_item.clone(), ordinal),
CeremonyRecordRef::agenda_item(agenda_item.clone()),
CeremonyReasonKind::Answers,
"a contribution made against this agenda item",
MemoryConfidence::High,
None,
now,
) {
self.reasons.push(reason);
}
}
}