use crate::FileType;
use anyhow::{bail, Result};
use clap::{command, Arg, ArgAction};
use std::path::{Path, PathBuf};
pub(crate) fn cli() -> Result<(PathBuf, PathBuf, Option<PathBuf>, FileType, bool, bool)> {
let matches = command!()
.arg(
Arg::new("verbose")
.action(ArgAction::SetTrue)
.long("verbose")
.short('v')
.help("Prints extra information and any recoverable errors to stderr."),
)
.arg(
Arg::new("strict")
.action(ArgAction::SetTrue)
.long("strict")
.short('s')
.help("Aborts if any unknown data are encountered during processing."),
)
.arg(
Arg::new("gym")
.action(ArgAction::SetTrue)
.long("gym")
.help("Sets the filetype to gym."),
)
.arg(
Arg::new("vgm")
.action(ArgAction::SetTrue)
.conflicts_with("gym")
.long("vgm")
.help("Sets the filetype to vgm."),
)
.arg(
Arg::new("zipped")
.action(ArgAction::SetTrue)
.requires("vgm")
.conflicts_with("gym")
.long("zipped")
.short('z')
.help("Extracts gzipped vgms (.vgz)"),
)
.arg(
Arg::new("config")
.long("config")
.help("Path to the desired config file."),
)
.arg(Arg::new("in").required(true).help(
"The file to be processed. Filetype is inferred by extension if not set with flags.",
))
.arg(
Arg::new("out")
.required(true)
.help("The path to a resulting midi file. Existing files will not be overwritten."),
)
.get_matches();
let in_path = PathBuf::from(matches.get_one::<String>("in").expect("Required"));
let out_path = PathBuf::from(matches.get_one::<String>("out").expect("Required"));
let verbose = matches.get_flag("verbose");
let strict = matches.get_flag("strict");
let config_path = matches
.get_one::<PathBuf>("config")
.map(|pb| pb.to_path_buf());
let file_type = match (
matches.get_flag("gym"),
matches.get_flag("vgm"),
matches.get_flag("zipped"),
) {
(true, false, false) => Ok(FileType::Gym),
(false, false, false) => determine_file_type(&in_path),
(false, true, false) => Ok(FileType::Vgm),
(false, true, true) => Ok(FileType::Vgz),
_ => bail!("Invalid flag combination"),
}?;
Ok((in_path, out_path, config_path, file_type, verbose, strict))
}
fn determine_file_type(in_path: &Path) -> Result<FileType> {
println!("File type flag not set. Attempting to determine file type.");
match in_path.extension().and_then(|osstr| osstr.to_str()) {
Some("gym") => {
println!("Determined file type to be gym from {}", in_path.display());
Ok(FileType::Gym)
},
Some("vgm") => {
println!("Determined file type to be vgm from {}", in_path.display());
Ok(FileType::Vgm)
},
Some("vgz") => {
println!("Determined file type to be vgz from {}", in_path.display());
Ok(FileType::Vgz)
},
_ => bail!("Unrecognized file extension from {}", in_path.display()),
}
}