use std::str::FromStr;
use filters::filter::Filter;
use chrono::NaiveDateTime;
use failure::Fallible as Result;
use failure::Error;
use resiter::Filter as RFilter;
use resiter::Map;
use resiter::AndThen;
use libimagrt::runtime::Runtime;
use libimagtimetrack::tag::TimeTrackingTag;
use libimagtimetrack::store::*;
use libimagtimetrack::iter::filter::has_end_time;
use libimagtimetrack::iter::filter::has_one_of_tags;
use libimagtimetrack::timetracking::TimeTracking;
pub fn stop(rt: &Runtime) -> Result<()> {
let (_, cmd) = rt.cli().subcommand();
let cmd = cmd.unwrap();
let stop_time = match cmd.value_of("stop-time") {
None | Some("now") => Ok(::chrono::offset::Local::now().naive_local()),
Some(ndt) => NaiveDateTime::from_str(ndt).map_err(Error::from),
}?;
let tags = cmd.values_of("tags").map(|tags| {
tags.map(String::from)
.map(TimeTrackingTag::from)
.collect()
});
let tags : Vec<TimeTrackingTag> = match tags {
Some(s) => s,
None => {
rt.store()
.get_timetrackings()?
.and_then_ok(|t| Ok((t.get_end_datetime()?.is_none(), t)))
.filter_ok(|tpl| (*tpl).0)
.map_ok(|tpl| tpl.1)
.and_then_ok(|t| t.get_timetrack_tag())
.collect::<Result<Vec<_>>>()?
}
};
let filter = has_end_time.not().and(has_one_of_tags(&tags));
rt
.store()
.get_timetrackings()?
.filter_ok(|e| filter.filter(e))
.and_then_ok(|mut elem| {
elem.set_end_datetime(stop_time.clone())?;
debug!("Setting end time worked: {:?}", elem);
rt.report_touched(elem.get_location()).map_err(Error::from)
})
.collect::<Result<Vec<_>>>()
.map(|_| ())
}