use std::path::PathBuf;
use clap::{ArgAction, ArgGroup, Parser, ValueEnum};
#[derive(Debug, Parser)]
#[command(author, version, about = "Query XLSX/XML/CSV/JSON/JSONL/Markdown datasets with SQL")]
#[command(
after_long_help = "Examples:\n\
qf --input ./input.xlsx:Sheet1 --query \"SELECT * FROM sheet\"\n\
qf --input ./inventory.xml:Inventory --query \"SELECT product, price FROM sheet WHERE active = 1\"\n\
qf --input ./inventory.csv --query \"SELECT product, price FROM sheet WHERE active = 1\"\n\
qf --input ./inventory.json:Inventory --query \"SELECT product, price FROM sheet WHERE active = 1\"\n\
qf --input ./inventory.jsonl --query \"SELECT product, price FROM sheet WHERE active = 1\"\n\
qf --input ./a.xlsx:Sheet1 --input ./b.csv --query \"SELECT * FROM sheet UNION ALL SELECT * FROM sheet2\"\n\
qf --input ./inventory.md --query \"SELECT product, price FROM sheet WHERE active = 1\"\n\
qf --input ./inventory.md:2 --query \"SELECT product, price FROM sheet\"\n\
qf --input ./input.xlsx --sheet Sheet1 --query-file ./query.sql --output ./result.csv --format csv"
)]
#[command(group(
ArgGroup::new("query_source")
.required(true)
.args(["query", "query_file"])
))]
pub(crate) struct Cli {
#[arg(
short,
long,
required = true,
action = ArgAction::Append,
value_name = "PATH[:SHEET|KEY]",
long_help = "Input dataset path. Supported formats: .xlsx, .xml, .csv, .json, .jsonl, .md, .markdown.\n\
For XLSX use PATH:SheetName (or PATH#SheetName) to select a worksheet.\n\
For XML use PATH:TagName (or PATH#TagName) to select a subtree; without sheet/tag the whole file is used.\n\
For JSON use PATH:Key (or PATH#Key) to select a top-level key; without key the whole JSON root is used.\n\
For Markdown use PATH:N (or PATH#N), where N is the 1-based table number in the document; without key the first table is used.\n\
CSV and JSONL do not support sheet/key selection."
)]
pub(crate) input: Vec<String>,
#[arg(
short,
long,
long_help = "Default sheet/tag/key applied to every --input that does not already specify one.\n\
Works with XLSX (worksheet), XML (tag), JSON (top-level key), and Markdown (1-based table number).\n\
Not supported for CSV and JSONL inputs."
)]
pub(crate) sheet: Option<String>,
#[arg(short, long, conflicts_with = "query_file")]
pub(crate) query: Option<String>,
#[arg(long = "query-file", conflicts_with = "query")]
pub(crate) query_file: Option<PathBuf>,
#[arg(long = "param", value_name = "NAME=VALUE", action = ArgAction::Append)]
pub(crate) params: Vec<String>,
#[arg(short, long)]
pub(crate) output: Option<PathBuf>,
#[arg(long, value_enum)]
pub(crate) format: Option<OutputFormat>,
#[arg(long = "no-headers")]
pub(crate) no_headers: bool,
}
#[derive(Clone, Debug, ValueEnum)]
pub(crate) enum OutputFormat {
Text,
Csv,
Jsonl,
Markdown,
Xlsx,
Xml,
}