use clap::{Args, Parser};
use serde::{Deserialize, Serialize};
use crate::inventory::options::{OutputFormat, ParameterKeyStyle, StorageType};
#[derive(Args, Debug, Default, Serialize, Deserialize)]
#[group(multiple = false, required = true)]
pub struct CommandOptions {
#[arg(short, long)]
pub inventory: bool,
#[arg(short, long, value_name = "NODENAME")]
pub nodeinfo: Option<String>,
}
#[derive(Args, Debug, Default, Deserialize, Serialize)]
#[group()]
pub struct OutputOptions {
#[arg(value_enum, short, long)]
pub output: Option<OutputFormat>,
#[arg(short = 'y', long)]
pub pretty_print: bool,
#[arg(long)]
pub output_sorted: bool,
#[arg(short = 'r', long)]
pub no_refs: bool,
#[arg(short = '0', long = "multiple-errors", conflicts_with = "single_error")]
pub group_errors: bool,
#[arg(short = '1', long = "single-error", conflicts_with = "group_errors")]
pub single_error: bool,
}
#[derive(Args, Debug, Default, Deserialize, Serialize)]
#[group()]
pub struct StorageOptions {
#[arg(value_enum, short, long)]
pub storage_type: Option<StorageType>,
#[arg(short = 'b', long)]
pub inventory_base_uri: Option<String>,
#[arg(short = 'u', long)]
pub nodes_uri: Option<String>,
#[arg(short = 'c', long)]
pub classes_uri: Option<String>,
#[arg(value_enum, short, long)]
pub parameter_key_style: Option<ParameterKeyStyle>,
#[arg(short = 'a', long)]
pub compose_node_name: bool,
#[arg(short = 'z', long)]
pub ignore_class_notfound: bool,
#[arg(short = 'x', long, value_name = "PATTERN")]
pub ignore_class_notfound_regexp: Option<Vec<String>>,
}
#[derive(Parser, Debug, Default, Serialize, Deserialize)]
#[serde(default)]
#[command(
name = "ferroclass",
bin_name = "ferroclass",
version,
about = "Hierarchical inventory management tool (reclass compatible)",
after_help = "Use --inventory to output the entire inventory as YAML or JSON.\n\
Use --nodeinfo NODENAME to output merged data for a specific node.\n\
\n\
Configuration is read from reclass-config.yml in the current\n\
directory or its parents. CLI options override config file values."
)]
pub struct Arguments {
#[arg(short, long)]
pub verbose: bool,
#[command(flatten, next_help_heading = "Database options")]
pub storage_options: StorageOptions,
#[command(flatten, next_help_heading = "Output options")]
pub output_options: OutputOptions,
#[command(flatten, next_help_heading = "Modes")]
pub command_options: CommandOptions,
}