use crate::cli::util::{YesNo, YesNoAuto};
use clap::{Args, Parser};

/// streaming time series processing tool
#[derive(Parser, Debug)]
#[clap(version)]
pub struct ChopArgs {
    /// sets the input files to use; if missing, stdin will be used
    #[clap(value_name = "file")]
    pub input: Vec<String>,

    /// output to a file; default output is stdout
    #[clap(short, long, value_name = "file")]
    pub output: Option<String>,

    /// output file format; detects based on file extension by default
    #[clap(long, value_name = "format")]
    pub output_format: Option<String>,

    /// input file format override list;
    /// applied in order of input file arguments;
    /// can use 'auto' to ask for file format auto-detection;
    /// if there are more input files than file format overrides,
    /// last format override will be used for remaining files;
    /// controls stdin format as appropriate; if missing, will attempt
    /// to autodetect file format first using file name, then using file contents
    #[clap(
        short,
        long,
        use_value_delimiter = true,
        require_value_delimiter = true,
        value_name = "f1[,f2[,etc]]"
    )]
    pub format: Option<Vec<String>>,

    /// optional - defaults to UTC; used for reading/writing date/time fields
    /// as needed; used for begin/end date args;
    /// checks env for CHOPPER_TZ before falling back to default
    #[clap(short = 'z', long, ignore_case = true, value_name = "arg")]
    pub timezone: Option<String>,

    /// set inclusive begin time to use to skip input data outside
    /// of the [begin, end) interval; auto-detects multiple formats
    /// including YYYY, YYYYMM, YYYYMMDD, YYYYMMDD-HHMMSS,
    /// some other select full date/time formats, ISO 8601, epoch timestamps in
    /// s/ms/us/ns between 1990 to 2033
    #[clap(short, long, value_name = "time")]
    pub begin: Option<String>,

    /// set exclusive end time to use to skip input data outside
    /// of the [begin, end) interval; same format as --begin
    #[clap(short, long, value_name = "time")]
    pub end: Option<String>,

    #[clap(flatten)]
    pub csv_in: ChopCsvInArgs,

    #[clap(flatten)]
    pub csv_out: ChopCsvOutArgs,
}

#[derive(Args, Debug)]
pub struct ChopCsvInArgs {
    /// csv input only: column delimiter [default: try each of ',\t ']
    #[clap(long, value_name("arg"))]
    pub csv_in_delimiter: Option<String>,

    /// csv input only: has header row?
    #[clap(
        arg_enum,
        long,
        default_value = "auto",
        ignore_case = true,
        value_name = "arg"
    )]
    pub csv_in_has_header: YesNoAuto,

    /// csv input only: specify the timestamp column name or index; will try to guess using obvious names, then fall back to column 0
    #[clap(long, value_name = "arg")]
    pub csv_in_ts_col: Option<String>,

    /// csv input only: specify the split timestamp date-only column name or index;
    /// used when date and time are in separate columns
    #[clap(
        long,
        value_name = "arg",
        requires = "csv-in-ts-col-time",
        conflicts_with_all = &["csv-in-ts-col", "csv-in-ts-fmt"],
    )]
    pub csv_in_ts_col_date: Option<String>,

    /// csv input only: specify the split timestamp time-only column name or index;
    /// used when date and time are in separate columns
    #[clap(
        long,
        value_name = "arg",
        requires = "csv-in-ts-col-date",
        conflicts_with_all = &["csv-in-ts-col", "csv-in-ts-fmt"],
    )]
    pub csv_in_ts_col_time: Option<String>,

    /// csv input only: specify the timestamp column format
    #[clap(long, value_name = "arg")]
    pub csv_in_ts_fmt: Option<String>,

    /// csv input only: specify the split timestamp date-only column format
    #[clap(
        long,
        value_name = "arg",
        requires = "csv-in-ts-fmt-time",
        conflicts_with_all = &["csv-in-ts-col", "csv-in-ts-fmt"],
    )]
    pub csv_in_ts_fmt_date: Option<String>,

    /// csv input only: specify the split timestamp time-only column format
    /// [default: %H:%M:%S]
    #[clap(
        long,
        value_name = "arg",
        requires = "csv-in-ts-fmt-time",
        conflicts_with_all = &["csv-in-ts-col", "csv-in-ts-fmt"],
    )]
    pub csv_in_ts_fmt_time: Option<String>,

    /// csv input only: timestamp is in epoch format with given granularity
    #[clap(
        long,
        value_name = "arg",
        possible_values = ["s", "ms", "us", "ns"],
        conflicts_with_all = &["csv-in-ts-col-date", "csv-in-ts-col-time", "csv-in-ts-fmt"],
    )]
    pub csv_in_epoch: Option<String>,
}

#[derive(Args, Debug)]
pub struct ChopCsvOutArgs {
    /// csv output only: name override for the auto-generated time column;
    /// default based on time column output format
    #[clap(long = "time-col-name", value_name = "arg")]
    pub csv_out_time_col_name: Option<String>,

    /// csv output only: time column has epoch timestamps
    #[clap(short = 'E', long = "epoch", conflicts_with = "csv-out-time-fmt-human")]
    pub csv_out_time_fmt_epoch: bool,

    /// csv output only: time column is human-readable; default
    #[clap(short = 'H', long = "human", conflicts_with = "csv-out-time-fmt-epoch")]
    pub csv_out_time_fmt_human: bool,

    /// csv output only: units of the auto-generated time column
    #[clap(
        short = 'g',
        long = "granularity",
        default_value = "ns",
        possible_values = ["s", "ms", "us", "ns"],
        value_name = "units",
    )]
    pub csv_out_time_col_units: String,

    /// csv output only: column delimiter
    #[clap(long = "delimiter", value_name = "arg", default_value = ",")]
    pub csv_out_delimiter: String,

    /// csv output only: print time as first column
    #[clap(
        arg_enum,
        long = "print-time",
        default_value = "yes",
        ignore_case = true,
        value_name = "arg"
    )]
    pub csv_out_print_time_col: YesNo,
}
