Documentation
//! Meka args and CLI handling

use clap::{ArgAction, Parser, Subcommand};
use std::path::PathBuf;

use crate::utils::MEKA_FILE;

/// meka args
#[derive(Parser, Debug)]
#[command(version, about, long_about = None,
    subcommand_required = true,
    arg_required_else_help = true,
)]
pub struct MekaArgs {
    /// Debug level (repeat -d for more verbosity)
    #[arg(short = 'd', visible_short_alias='v',  action = ArgAction::Count)]
    pub debug: u8,

    /// Subcommand
    #[command(subcommand)]
    pub command: Commands,
}

/// meka subcommands
#[derive(Subcommand, Debug)]
pub enum Commands {
    /// Run the tool and optionally write results to a file
    #[command(visible_alias = "run")]
    Record(RunArgs),

    /// Perform analysis
    #[command(visible_alias = "analyse")]
    Analyze(AnalyzeArgs),
}

/// Arguments for the "run" command
#[derive(Debug, Parser)]
pub struct RunArgs {
    /// global debug flag
    #[arg(global = true, short = 'd', visible_short_alias='v', action = ArgAction::Count)]
    pub debug: u8,

    /// Alias for -o=-
    /// Output on standard output
    #[arg(long = "json", action = ArgAction::SetTrue)]
    pub json_output: bool,

    /// Capture environ
    #[arg(long, action = ArgAction::SetTrue)]
    pub capture_environ: bool,

    /// Capture status
    #[arg(long, action = ArgAction::SetTrue)]
    pub capture_status: bool,

    /// Write file at each insert
    #[arg(long, action = ArgAction::SetTrue)]
    pub write_on_insert: bool,

    /// Relative Pid
    #[arg(long, action = ArgAction::SetTrue)]
    pub relative_pid: bool,

    /// Change the cwd
    #[arg(long, alias = "pwd")]
    pub cwd: Option<PathBuf>,

    /// Override the PATH environment variable for command lookup
    #[arg(long = "path", value_name = "PATH")]
    pub path_var: Option<Vec<PathBuf>>,

    /// Output file (e.g. file.json)
    #[arg(
        short = 'o',
        long = "output",
        value_name = "RECORDING_FILE",
        default_value = MEKA_FILE
    )]
    pub output_file: String,

    /// Command to test
    #[arg(value_name = "COMMAND LINE", required = true)]
    pub inputs: Vec<String>,

    /// Wrap args in shell
    #[arg(long, action = ArgAction::SetTrue)]
    pub wrap_shell: bool,
}

/// Arguments for the "analyze" command
#[derive(Debug, Parser)]
pub struct AnalyzeArgs {
    /// global debug flag
    #[arg(global = true, short = 'd', visible_short_alias='v', action = ArgAction::Count)]
    pub debug: u8,

    /// Minimum command size to print
    #[arg(long, default_value_t = 50)]
    pub min_cmd_size: usize,

    /// Optional name of file
    #[arg(value_name = "RECORDING_FILE", default_value = MEKA_FILE)]
    pub input_file: String,
}