#![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
use std::marker::PhantomData;
use std::sync::Mutex;
use crate::error::Error;
use crate::scopes::{GetSendStatusCapable, PcsExternalScopeSet, SendAlertCapable};
use crate::types::{
PollConfig, RecipientList, SendOutcome, SendRequestId, SendRequestState, SendStatus,
SendStatusTotals, TemplateId,
};
#[derive(Debug, Clone)]
pub struct RecordedSend {
pub template: TemplateId,
pub recipients: RecipientList,
pub poll: Option<PollConfig>,
}
#[derive(Debug, Default)]
struct State {
sends: Vec<RecordedSend>,
next_send_outcome: Option<Result<SendOutcome, Error>>,
next_status: Option<Result<SendStatus, Error>>,
}
pub struct MemoryPcsExternal<S: PcsExternalScopeSet> {
state: Mutex<State>,
_scope: PhantomData<S>,
}
impl<S: PcsExternalScopeSet> std::fmt::Debug for MemoryPcsExternal<S> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("MemoryPcsExternal").finish()
}
}
impl<S: PcsExternalScopeSet> MemoryPcsExternal<S> {
#[must_use]
pub fn new() -> Self {
Self {
state: Mutex::new(State::default()),
_scope: PhantomData,
}
}
pub fn send_calls(&self) -> Vec<RecordedSend> {
self.state.lock().unwrap().sends.clone()
}
}
impl<S: SendAlertCapable> MemoryPcsExternal<S> {
pub fn with_send_outcome(self, outcome: Result<SendOutcome, Error>) -> Self {
self.state.lock().unwrap().next_send_outcome = Some(outcome);
self
}
pub async fn send_alert(
&self,
template: &TemplateId,
recipients: &RecipientList,
poll: Option<&PollConfig>,
) -> Result<SendOutcome, Error> {
let mut state = self.state.lock().unwrap();
state.sends.push(RecordedSend {
template: template.clone(),
recipients: recipients.clone(),
poll: poll.cloned(),
});
state.next_send_outcome.take().unwrap_or_else(|| {
Ok(SendOutcome {
id: SendRequestId::new("fake-id"),
state: SendRequestState::Queued,
total_recipients: recipients.len() as u32,
})
})
}
}
impl<S: GetSendStatusCapable> MemoryPcsExternal<S> {
pub async fn get_send_status(&self, id: &SendRequestId) -> Result<SendStatus, Error> {
let mut state = self.state.lock().unwrap();
state.next_status.take().unwrap_or_else(|| {
Ok(SendStatus {
id: id.clone(),
state: SendRequestState::Completed,
totals: SendStatusTotals::default(),
})
})
}
}