use chrono::{FixedOffset, NaiveTime};
use chrono_tz::Tz;
#[cfg(feature = "clap")]
use clap::Parser;
use getset::Getters;
use pace_time::{date_time::PaceDateTime, time_zone::PaceTimeZoneKind, Validate};
use tracing::debug;
use typed_builder::TypedBuilder;
use crate::{
commands::EndOptions,
config::PaceConfig,
error::{PaceResult, UserMessage},
service::activity_store::ActivityStore,
storage::{get_storage_from_config, ActivityStateManagement, SyncStorage},
};
#[derive(Debug, Clone, PartialEq, TypedBuilder, Eq, Hash, Default, Getters)]
#[getset(get = "pub")]
#[non_exhaustive]
#[cfg_attr(feature = "clap", derive(Parser))]
#[cfg_attr(
feature = "clap", clap(group = clap::ArgGroup::new("tz").multiple(false).required(false)))]
pub struct EndCommandOptions {
#[cfg_attr(
feature = "clap",
clap(short, long, value_name = "Finishing Time", visible_alias = "end")
)]
at: Option<NaiveTime>,
#[cfg_attr(
feature = "clap",
clap(
short = 'z',
long,
value_name = "Time Zone",
group = "tz",
visible_alias = "tz"
)
)]
time_zone: Option<Tz>,
#[cfg_attr(
feature = "clap",
clap(
short = 'Z',
long,
value_name = "Time Zone Offset",
group = "tz",
visible_alias = "tzo"
)
)]
time_zone_offset: Option<FixedOffset>,
}
impl EndCommandOptions {
#[tracing::instrument(skip(self))]
pub fn handle_end(&self, config: &PaceConfig) -> PaceResult<UserMessage> {
let Self {
at,
time_zone,
time_zone_offset,
..
} = self;
let date_time = PaceDateTime::try_from((
at.as_ref(),
PaceTimeZoneKind::try_from((time_zone.as_ref(), time_zone_offset.as_ref()))?,
PaceTimeZoneKind::from(config.general().default_time_zone().as_ref()),
))?
.validate()?;
debug!("Parsed date time: {:?}", date_time);
let activity_store = ActivityStore::with_storage(get_storage_from_config(config)?)?;
let end_opts = EndOptions::builder().end_time(date_time).build();
let user_message = (activity_store.end_all_activities(end_opts)?).map_or_else(
|| "No unfinished activities to end.".to_string(),
|unfinished_activities| {
let mut msgs = vec![];
for activity in &unfinished_activities {
debug!("Ended {}", activity.activity());
msgs.push(format!("Ended {}", activity.activity()));
}
msgs.join("\n")
},
);
activity_store.sync()?;
Ok(UserMessage::new(user_message))
}
}