use super::Command;
use std::borrow::Cow;

use shell_quote::Quote;

pub fn command_to_string(cmd: &Command) -> String {
    let program = escape_cli(cmd.get_program());
    let env: Vec<_> = cmd
        .get_envs()
        .map(|(key, value)| match value {
            None => key.into(),
            Some(value) => Cow::Owned(format!(
                "{key}={value} ",
                value = escape_cli(value.as_potentially_redacted_str())
            )),
        })
        .collect();
    let args: Vec<_> = cmd.get_args().map(escape_cli).collect();
    let env = env.join("");
    let args = args.join(" ");
    format!(
        "{env_marker}{env}{program}{arg_separator}{args}",
        env_marker = if env.is_empty() { "" } else { "env " },
        arg_separator = if args.is_empty() { "" } else { " " }
    )
}

fn escape_cli<A: AsRef<str>>(str: A) -> String {
    let str = str.as_ref();
    shell_quote::Bash::quote(str)
}
