use clap::{Parser, Subcommand};
use std::path::PathBuf;
#[derive(Parser, Debug)]
#[command(
name = "cleansh",
author = "Cleansh Technologies (Clean Shell)", // Added author as per best practice
version = env!("CARGO_PKG_VERSION"), // Use env! for version
about = "Securely redact sensitive data from text",
long_about = "Cleansh is a command-line utility for securely redacting sensitive information from text-based data. It helps you sanitize logs, code, documents, or terminal output to ensure that Personally Identifiable Information (PII) and other sensitive patterns are removed or obfuscated according to a configurable rule set.",
// Crucial for cli_integration_tests:
// Allow options to be placed anywhere on the command line, not just before subcommands
arg_required_else_help = false, // Display help if no arguments, but don't require args if a subcommand is chosen
allow_missing_positional = true, // Allows for flexible argument order without strict positional requirements
allow_external_subcommands = true, // Allows for future custom commands if needed
)]
pub struct Cli {
#[arg(short = 'c', long = "clipboard", conflicts_with = "no_clipboard", help = "Copy sanitized output to the system clipboard.")]
pub clipboard: bool,
#[arg(long = "no-clipboard", conflicts_with = "clipboard", help = "Explicitly prevent copying output to clipboard.")]
pub no_clipboard: bool,
#[arg(short = 'D', long = "diff", conflicts_with = "no_diff", help = "Show a unified diff to highlight the changes made during the sanitization process.")] pub diff: bool,
#[arg(long = "no-diff", conflicts_with = "diff", help = "Explicitly prevent showing a diff.")]
pub no_diff: bool,
#[arg(long = "config", value_name = "FILE", help = "Path to a custom redaction configuration file (YAML).")] pub config: Option<PathBuf>,
#[arg(long = "rules", value_name = "NAME", help = "Name of a specific rule set/profile to apply.")] pub rules: Option<String>,
#[arg(short = 'o', long = "output", value_name = "FILE", help = "Write output to a specified file instead of stdout.")] pub output: Option<PathBuf>,
#[arg(long = "no-redaction-summary", help = "Suppress the redaction summary.")] pub no_summary: bool,
#[arg(short = 'e', long = "enable", value_delimiter = ',', help = "Explicitly enable only these rule names (comma-separated).")] pub enable: Vec<String>,
#[arg(short = 'x', long = "disable", value_delimiter = ',', help = "Explicitly disable these rule names (comma-separated).")] pub disable: Vec<String>,
#[arg(long, short = 'i', value_name = "FILE", help = "Read input from a specified file instead of stdin.")] pub input_file: Option<PathBuf>,
#[arg(long, help = "Process input line by line (useful for streaming data from pipes).")]
pub line_buffered: bool,
#[arg(long, short = 'q', help = "Suppress all informational and debug messages.")]
pub quiet: bool,
#[arg(long, short = 'd', help = "Enable debug logging.")] pub debug: bool,
#[arg(long = "disable-debug", help = "Disable debug logging, overriding RUST_LOG.")]
pub disable_debug: bool,
#[arg(long = "theme", value_name = "FILE", help = "Specify the path to a custom YAML theme file.")] pub theme: Option<PathBuf>,
#[arg(long = "disable-donation-prompts", help = "Disable future prompts for donations.")]
pub disable_donation_prompts: bool,
#[command(subcommand)]
pub command: Option<Commands>,
}
#[derive(Subcommand, Debug)]
pub enum Commands {
#[command(about = "Analyze input for sensitive data and provide a summary without redacting it, providing statistics.")]
Stats(StatsCommand),
#[command(about = "Uninstall cleansh and remove its associated files.")]
Uninstall {
#[arg(long, short = 'y', help = "Proceed with uninstallation without a confirmation prompt.")]
yes: bool,
},
}
#[derive(Parser, Debug)]
pub struct StatsCommand {
#[arg(long = "json-file", value_name = "FILE", help = "Export the redaction statistics to a JSON file.")]
pub json_file: Option<PathBuf>,
#[arg(long = "json-stdout", conflicts_with = "json_file", help = "Export the redaction statistics to stdout as JSON.")] pub json_stdout: bool,
#[arg(long = "sample-matches", value_name = "N", help = "Display a sample of up to N unique matches per rule in the console output.")]
pub sample_matches: Option<usize>,
#[arg(long = "fail-over-threshold", value_name = "N", help = "Exit with a non-zero code if the total number of detected secrets exceeds this threshold.")]
pub fail_over_threshold: Option<usize>,
}