use clap::Command;
use std::io::Write;

/// The usage spec for a clap command, ready to inspect or annotate.
///
/// [`generate`] writes this straight out. Take it here instead when you need
/// to set something clap cannot express — most often `effect=`, which says
/// whether a command reads, writes or destroys:
///
/// ```no_run
/// # use clap::Command;
/// # use clap_usage::usage::SpecCommandEffect;
/// # let mut cmd = Command::new("mycli").subcommand(Command::new("rm"));
/// let mut spec = clap_usage::spec(&mut cmd, "mycli");
/// if let Some(rm) = spec.cmd.subcommands.get_mut("rm") {
///     rm.effect = Some(SpecCommandEffect::Destructive);
/// }
/// println!("{spec}");
/// ```
pub fn spec<S: Into<String>>(cmd: &mut Command, bin_name: S) -> usage::Spec {
    let mut spec: usage::Spec = cmd.clone().into();
    spec.bin = bin_name.into();
    spec
}

/// Write the usage spec for a clap command, with the `@generated` header.
///
/// Use [`spec`] instead if you need to modify the spec before writing it.
pub fn generate<S: Into<String>>(cmd: &mut Command, bin_name: S, buf: &mut dyn Write) {
    let spec = spec(cmd, bin_name);

    writeln!(buf, "// @generated by usage-cli from clap metadata")
        .expect("write @generated comment");
    writeln!(buf, "{spec}").expect("write usage spec");
}
