1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
use clap::Parser;
use std::path::PathBuf;
use sarpro::types::{OutputFormat, SyntheticRgbMode};
use sarpro::{AutoscaleStrategy, BitDepthArg, InputFormat, Polarization};
#[derive(Parser)]
#[command(name = "sarpro", version, about = "SARPRO CLI")]
pub struct CliArgs {
/// Input SAFE directory (single file mode) local or remote HTTP via GDAL VSI (unzipped .SAFE)
#[arg(short, long)]
pub input: Option<PathBuf>,
/// Input directory containing SAFE subdirectories (batch mode)
#[arg(long)]
pub input_dir: Option<PathBuf>,
/// Output filename (single file mode)
#[arg(short, long)]
pub output: Option<PathBuf>,
/// Output directory for batch processing (batch mode)
#[arg(long)]
pub output_dir: Option<PathBuf>,
/// Output format (tiff or jpeg)
#[arg(short = 'f', long, value_enum, default_value_t = OutputFormat::TIFF)]
pub format: OutputFormat,
/// Input format (only SAFE supported currently)
#[arg(long, value_enum, default_value_t = InputFormat::Safe)]
pub input_format: InputFormat,
/// Output bit depth (8 or 16)
#[arg(long, value_enum, default_value_t = BitDepthArg::U8)]
pub bit_depth: BitDepthArg,
/// Polarization mode (vv, vh, hh, hv or multiband)
#[arg(long, value_enum, default_value_t = Polarization::Vv)]
pub polarization: Polarization,
/// Autoscaling strategy (standard, robust, adaptive, equalized, clahe, default)
#[arg(long, value_enum, default_value_t = AutoscaleStrategy::Clahe)]
pub autoscale: AutoscaleStrategy,
/// Image size for scaling. Options:
/// - Predefined: 512, 1024, 2048
/// - Custom: any positive integer (e.g., 1536)
/// - Original: "original" (no scaling)
#[arg(long, default_value = "original")]
pub size: String,
/// Enable logging
#[arg(long, default_value_t = false)]
pub log: bool,
/// Batch mode: continue processing other files when encountering unsupported products
#[arg(long, default_value_t = false)]
pub batch: bool,
/// Add padding to make square images (centers image and adds zero padding to top/bottom)
#[arg(long, default_value_t = false)]
pub pad: bool,
/// Optional target CRS for map reprojection (e.g., EPSG:4326, EPSG:32633).
/// Special values: 'auto' (detect UTM from metadata), 'none' (disable)
#[arg(long)]
pub target_crs: Option<String>,
/// Optional resampling algorithm (nearest, bilinear, cubic, lanczos)
#[arg(long)]
pub resample_alg: Option<String>,
/// Synthetic RGB mode (only used when --format jpeg and --polarization multiband)
#[arg(long = "synrgb-mode", value_enum, default_value_t = SyntheticRgbMode::Default)]
pub synrgb_mode: SyntheticRgbMode,
/// Open a remote authenticated CDSE/ASF SAFE packaged as a ZIP via VSICURL/VSIZIP
#[arg(long = "safe-zip-url")]
pub safe_zip_url: Option<String>,
/// Directory for remote cache/materialization (required for remote ZIPs)
#[arg(long = "remote-cache-dir")]
pub remote_cache_dir: Option<PathBuf>,
/// Explicit measurement URLs (VSICURL). Use with --polarization appropriately
#[arg(long = "vv-url")]
pub vv_url: Option<String>,
#[arg(long = "vh-url")]
pub vh_url: Option<String>,
#[arg(long = "hh-url")]
pub hh_url: Option<String>,
#[arg(long = "hv-url")]
pub hv_url: Option<String>,
/// Phase 1 non-breaking additions below ---> TO BE WIRED --->
/// Load inputs from a STAC Item (local file path or HTTP URL)
#[arg(long = "stac-item")]
pub stac_item: Option<String>,
/// Newline-separated list of inputs (STAC Items, SAFE ZIP URLs, local SAFE paths, or direct band URLs)
#[arg(long = "input-list")]
pub input_list: Option<PathBuf>,
/// OAuth bearer token to access authenticated endpoints (mapped to GDAL headers later)
#[arg(long = "auth-bearer")]
pub auth_bearer: Option<String>,
/// HTTP timeout in seconds for remote reads (GDAL)
#[arg(long = "http-timeout", default_value_t = 120u64)]
pub http_timeout: u64,
/// Number of HTTP retries for transient errors
#[arg(long = "http-retries", default_value_t = 3u32)]
pub http_retries: u32,
/// Base backoff in milliseconds between retries
#[arg(long = "http-backoff-ms", default_value_t = 500u64)]
pub http_backoff_ms: u64,
/// Maximum number of concurrent entries to process when using --input-list
#[arg(long = "max-concurrent")]
pub max_concurrent: Option<usize>,
}