use std::sync::Arc;
use chrono::{DateTime, Utc};
use oxios_calendar::{
AlarmEvent, CalendarEngine, CreateResult, Event, EventDraft, EventPatch, FreeBusySlot,
UpdateResult,
};
use crate::event_bus::{EventBus, KernelEvent};
pub struct CalendarApi {
pub engine: Arc<CalendarEngine>,
event_bus: Option<EventBus>,
}
impl CalendarApi {
pub fn new(engine: Arc<CalendarEngine>) -> Self {
Self {
engine,
event_bus: None,
}
}
pub fn with_event_bus(engine: Arc<CalendarEngine>, event_bus: EventBus) -> Self {
Self {
engine,
event_bus: Some(event_bus),
}
}
pub async fn create(&self, draft: EventDraft) -> anyhow::Result<CreateResult> {
let title = draft.title.clone();
let start = draft.start.to_rfc3339();
let end = draft.end.to_rfc3339();
let result = self.engine.create(draft).await?;
if let Some(bus) = &self.event_bus {
let _ = bus.publish(KernelEvent::CalendarEventCreated {
uid: result.uid.clone(),
title,
start,
end,
});
}
Ok(result)
}
pub async fn update(&self, uid: &str, patch: EventPatch) -> anyhow::Result<UpdateResult> {
let result = self.engine.update(uid, patch).await?;
if let Some(bus) = &self.event_bus {
let title = self
.engine
.get(uid)
.await
.map(|e| e.title.clone())
.unwrap_or_default();
let _ = bus.publish(KernelEvent::CalendarEventUpdated {
uid: result.uid.clone(),
title,
});
}
Ok(result)
}
pub async fn delete(&self, uid: &str) -> anyhow::Result<()> {
let title = self
.engine
.get(uid)
.await
.map(|e| e.title.clone())
.unwrap_or_default();
self.engine.delete(uid).await?;
if let Some(bus) = &self.event_bus {
let _ = bus.publish(KernelEvent::CalendarEventDeleted {
uid: uid.to_string(),
title,
});
}
Ok(())
}
pub async fn get(&self, uid: &str) -> anyhow::Result<Event> {
self.engine.get(uid).await
}
pub async fn list(&self, from: DateTime<Utc>, to: DateTime<Utc>) -> anyhow::Result<Vec<Event>> {
self.engine.list(from, to).await
}
pub async fn search(&self, query: &str) -> anyhow::Result<Vec<Event>> {
self.engine.search(query).await
}
pub async fn freebusy(
&self,
from: DateTime<Utc>,
to: DateTime<Utc>,
) -> anyhow::Result<Vec<FreeBusySlot>> {
self.engine.freebusy(from, to).await
}
pub fn find_pending_alarms(&self, from: DateTime<Utc>, to: DateTime<Utc>) -> Vec<AlarmEvent> {
self.engine.find_pending_alarms(from, to)
}
}