use crate::network::{IoEvent, Network};
use crate::user_config::UserConfig;
use super::{
util::{Flag, JumpDirection, Type},
CliApp,
};
use anyhow::{anyhow, Result};
use clap::ArgMatches;
pub async fn handle_matches(
matches: &ArgMatches,
cmd: String,
net: Network,
config: UserConfig,
) -> Result<String> {
let mut cli = CliApp::new(net, config);
cli.net.handle_network_event(IoEvent::GetDevices).await;
cli
.net
.handle_network_event(IoEvent::GetCurrentPlayback)
.await;
let devices_list = match &cli.net.app.lock().await.devices {
Some(p) => p
.devices
.iter()
.filter_map(|d| d.id.clone())
.collect::<Vec<String>>(),
None => Vec::new(),
};
let device_id = cli.net.client_config.device_id.clone();
let needs_device = match &device_id {
Some(id) => !devices_list.contains(id),
None => true,
};
if needs_device {
if let Some(d) = devices_list.first() {
cli.net.client_config.set_device_id(d.clone())?;
}
}
if let Some(d) = matches.get_one::<String>("device") {
cli.set_device(d.to_string()).await?;
}
let output = match cmd.as_str() {
"playback" => {
let format = matches.get_one::<String>("format").unwrap();
if matches.get_flag("share-track") {
return cli.share_track_or_episode().await;
} else if matches.get_flag("share-album") {
return cli.share_album_or_show().await;
}
if matches.get_flag("toggle") {
cli.toggle_playback().await;
}
if let Some(d) = matches.get_one::<String>("transfer") {
cli.transfer_playback(d).await?;
}
if matches.contains_id("flags") && matches.get_many::<String>("flags").is_some() {
let flags = Flag::from_matches(matches);
for f in flags {
cli.mark(f).await?;
}
} else {
let flags = Flag::from_matches(matches);
for f in flags {
cli.mark(f).await?;
}
}
if matches.get_count("next") > 0 || matches.get_count("previous") > 0 {
let (direction, amount) = JumpDirection::from_matches(matches);
for _ in 0..amount {
cli.jump(&direction).await;
}
}
if let Some(vol) = matches.get_one::<String>("volume") {
cli.volume(vol.to_string()).await?;
}
if let Some(secs) = matches.get_one::<String>("seek") {
cli.seek(secs.to_string()).await?;
}
cli.get_status(format.to_string()).await
}
"play" => {
let queue = matches.get_flag("queue");
let random = matches.get_flag("random");
let format = matches.get_one::<String>("format").unwrap();
if let Some(uri) = matches.get_one::<String>("uri") {
cli.play_uri(uri.to_string(), queue, random).await;
} else if let Some(name) = matches.get_one::<String>("name") {
let category = Type::play_from_matches(matches);
cli.play(name.to_string(), category, queue, random).await?;
}
cli.get_status(format.to_string()).await
}
"list" => {
let format = matches.get_one::<String>("format").unwrap().to_string();
if let Some(max) = matches.get_one::<String>("limit") {
cli.update_query_limits(max.to_string()).await?;
}
let category = Type::list_from_matches(matches);
Ok(cli.list(category, &format).await)
}
"search" => {
let format = matches.get_one::<String>("format").unwrap().to_string();
if let Some(max) = matches.get_one::<String>("limit") {
cli.update_query_limits(max.to_string()).await?;
}
let category = Type::search_from_matches(matches);
Ok(
cli
.query(
matches.get_one::<String>("search").unwrap().to_string(),
format,
category,
)
.await,
)
}
_ => unreachable!(),
};
let api_error = cli.net.app.lock().await.api_error.clone();
if api_error.is_empty() {
output
} else {
Err(anyhow!("{}", api_error))
}
}