subx_cli/commands/config_command.rs
1//! Configuration management command implementation with hierarchical settings.
2//!
3//! This module provides comprehensive configuration management capabilities
4//! through the `config` subcommand, enabling users to view, modify, and manage
5//! application settings across multiple configuration categories and sources.
6//! It supports hierarchical configuration with validation and type safety.
7//!
8//! # Configuration Architecture
9//!
10//! ## Configuration Categories
11//! - **General**: Basic application behavior and preferences
12//! - **AI Settings**: AI service providers, models, and API configuration
13//! - **Audio Processing**: Audio analysis and synchronization parameters
14//! - **Format Options**: Default output formats and conversion settings
15//! - **Cache Management**: Caching behavior and storage configuration
16//! - **Sync Settings**: Subtitle timing and synchronization options
17//!
18//! ## Configuration Sources (Priority Order)
19//! 1. **Command-line Arguments**: Highest priority, session-specific
20//! 2. **Environment Variables**: Runtime configuration overrides
21//! 3. **User Configuration**: Personal settings in user config directory
22//! 4. **Project Configuration**: Local project-specific settings
23//! 5. **System Configuration**: Global system-wide defaults
24//! 6. **Built-in Defaults**: Application default values
25//!
26//! # Supported Operations
27//!
28//! ## Set Operation
29//! - **Type Validation**: Ensure values match expected data types
30//! - **Range Checking**: Validate numeric values are within bounds
31//! - **Format Verification**: Check string values follow required patterns
32//! - **Dependency Validation**: Verify related settings are compatible
33//! - **Backup Creation**: Preserve previous values for rollback
34//!
35//! ## Get Operation
36//! - **Value Display**: Show current effective value
37//! - **Source Identification**: Indicate where value originates
38//! - **Type Information**: Display expected data type and constraints
39//! - **Default Comparison**: Show difference from built-in defaults
40//! - **Metadata Display**: Include help text and validation rules
41//!
42//! ## List Operation
43//! - **Categorized Display**: Group settings by functional area
44//! - **Source Indicators**: Show which settings are customized
45//! - **Value Formatting**: Display values in appropriate format
46//! - **Filter Options**: Support for category and status filtering
47//! - **Export Capability**: Generate configuration for sharing
48//!
49//! ## Reset Operation
50//! - **Backup Creation**: Automatic backup before reset
51//! - **Selective Reset**: Option to reset specific categories
52//! - **Confirmation Process**: Interactive confirmation for safety
53//! - **Recovery Information**: Instructions for backup restoration
54//!
55//! # Configuration Keys
56//!
57//! ## General Settings
58//! ```text
59//! general.enable_progress_bar # Boolean: Show progress indicators
60//! general.backup_enabled # Boolean: Automatic file backups
61//! general.log_level # String: Logging verbosity level
62//! general.timeout # Integer: Operation timeout in seconds
63//! ```
64//!
65//! ## AI Configuration
66//! ```text
67//! ai.provider # String: AI service provider
68//! ai.openai.api_key # String: OpenAI API authentication
69//! ai.openai.model # String: GPT model selection
70//! ai.openai.max_tokens # Integer: Maximum response length
71//! ai.anthropic.api_key # String: Anthropic API authentication
72//! ai.max_sample_length # Integer: Text sample size for analysis
73//! ai.enable_cache # Boolean: Cache AI responses
74//! ```
75//!
76//! ## Audio Processing
77//! ```text
78//! audio.max_offset_seconds # Float: Maximum sync offset range
79//! audio.correlation_threshold # Float: Minimum correlation for sync
80//! audio.dialogue_threshold # Float: Speech detection sensitivity
81//! audio.min_dialogue_duration_ms # Integer: Minimum speech segment length
82//! audio.enable_dialogue_detection # Boolean: Advanced audio analysis
83//! ```
84//!
85//! # Examples
86//!
87//! ```rust,ignore
88//! use subx_cli::cli::{ConfigArgs, ConfigAction};
89//! use subx_cli::commands::config_command;
90//!
91//! // Set AI provider
92//! let set_args = ConfigArgs {
93//! action: ConfigAction::Set {
94//! key: "ai.provider".to_string(),
95//! value: "openai".to_string(),
96//! },
97//! };
98//! config_command::execute(set_args).await?;
99//!
100//! // Get current AI model
101//! let get_args = ConfigArgs {
102//! action: ConfigAction::Get {
103//! key: "ai.openai.model".to_string(),
104//! },
105//! };
106//! config_command::execute(get_args).await?;
107//! ```
108
109use crate::cli::{ConfigAction, ConfigArgs};
110use crate::config::ConfigService;
111use crate::error::{SubXError, SubXResult};
112
113/// Execute configuration management operations with validation and type safety.
114///
115/// This function provides the main entry point for all configuration management
116/// operations, including setting values, retrieving current configuration,
117/// listing all settings, and resetting to defaults. It includes comprehensive
118/// validation, error handling, and user-friendly output formatting.
119///
120/// # Operation Workflow
121///
122/// ## Set Operation
123/// 1. **Configuration Loading**: Load current configuration from all sources
124/// 2. **Key Validation**: Verify configuration key exists and is writable
125/// 3. **Value Parsing**: Convert string value to appropriate data type
126/// 4. **Constraint Checking**: Validate value meets all requirements
127/// 5. **Dependency Verification**: Check related settings compatibility
128/// 6. **Backup Creation**: Save current value for potential rollback
129/// 7. **Value Application**: Update configuration with new value
130/// 8. **Persistence**: Save updated configuration to appropriate file
131/// 9. **Confirmation**: Display success message with applied value
132///
133/// ## Get Operation
134/// 1. **Configuration Loading**: Load current effective configuration
135/// 2. **Key Resolution**: Locate requested configuration setting
136/// 3. **Source Identification**: Determine where value originates
137/// 4. **Value Formatting**: Format value for appropriate display
138/// 5. **Metadata Retrieval**: Gather type and constraint information
139/// 6. **Output Generation**: Create comprehensive information display
140///
141/// ## List Operation
142/// 1. **Configuration Loading**: Load all configuration settings
143/// 2. **Categorization**: Group settings by functional area
144/// 3. **Source Analysis**: Identify customized vs. default values
145/// 4. **Formatting**: Prepare values for tabular display
146/// 5. **Output Generation**: Create organized configuration overview
147///
148/// ## Reset Operation
149/// 1. **Current State Backup**: Create timestamped configuration backup
150/// 2. **User Confirmation**: Interactive confirmation for destructive operation
151/// 3. **Default Restoration**: Replace all settings with built-in defaults
152/// 4. **Validation**: Verify reset configuration is valid
153/// 5. **Persistence**: Save default configuration to user config file
154/// 6. **Confirmation**: Display reset completion and backup location
155///
156/// # Type System Integration
157///
158/// The configuration system provides strong typing with automatic conversion:
159/// - **Boolean Values**: "true", "false", "1", "0", "yes", "no"
160/// - **Integer Values**: Decimal notation with range validation
161/// - **Float Values**: Decimal notation with precision preservation
162/// - **String Values**: UTF-8 text with format validation where applicable
163/// - **Array Values**: JSON array format for complex configuration
164///
165/// # Validation Framework
166///
167/// Each configuration setting includes comprehensive validation:
168/// - **Type Constraints**: Must match expected data type
169/// - **Range Limits**: Numeric values within acceptable bounds
170/// - **Format Requirements**: String values matching required patterns
171/// - **Dependency Rules**: Related settings must be compatible
172/// - **Security Checks**: Sensitive values properly protected
173///
174/// # Arguments
175///
176/// * `args` - Configuration command arguments containing the specific
177/// operation to perform (set, get, list, or reset) along with any
178/// required parameters such as key names and values.
179///
180/// # Returns
181///
182/// Returns `Ok(())` on successful operation completion, or an error describing:
183/// - Configuration loading or parsing failures
184/// - Invalid configuration keys or malformed key paths
185/// - Type conversion or validation errors
186/// - File system access problems during persistence
187/// - User cancellation of destructive operations
188///
189/// # Error Categories
190///
191/// ## Configuration Errors
192/// - **Invalid Key**: Specified configuration key does not exist
193/// - **Type Mismatch**: Value cannot be converted to expected type
194/// - **Range Error**: Numeric value outside acceptable range
195/// - **Format Error**: String value doesn't match required pattern
196/// - **Dependency Error**: Value conflicts with related settings
197///
198/// ## System Errors
199/// - **File Access**: Cannot read or write configuration files
200/// - **Permission Error**: Insufficient privileges for operation
201/// - **Disk Space**: Insufficient space for configuration persistence
202/// - **Corruption**: Configuration file is damaged or invalid
203///
204/// # Security Considerations
205///
206/// - **Sensitive Values**: API keys and credentials are properly masked in output
207/// - **File Permissions**: Configuration files created with appropriate permissions
208/// - **Backup Protection**: Backup files inherit security settings
209/// - **Validation**: All input values sanitized and validated
210///
211/// # Examples
212///
213/// ```rust,ignore
214/// use subx_cli::cli::{ConfigArgs, ConfigAction};
215/// use subx_cli::commands::config_command;
216///
217/// // Configure AI service with API key
218/// let ai_setup = ConfigArgs {
219/// action: ConfigAction::Set {
220/// key: "ai.openai.api_key".to_string(),
221/// value: "sk-1234567890abcdef".to_string(),
222/// },
223/// };
224/// config_command::execute(ai_setup).await?;
225///
226/// // Adjust audio processing sensitivity
227/// let audio_tuning = ConfigArgs {
228/// action: ConfigAction::Set {
229/// key: "audio.correlation_threshold".to_string(),
230/// value: "0.85".to_string(),
231/// },
232/// };
233/// config_command::execute(audio_tuning).await?;
234///
235/// // View complete configuration
236/// let view_all = ConfigArgs {
237/// action: ConfigAction::List,
238/// };
239/// config_command::execute(view_all).await?;
240///
241/// // Reset to clean state
242/// let reset_config = ConfigArgs {
243/// action: ConfigAction::Reset,
244/// };
245/// config_command::execute(reset_config).await?;
246/// ```
247pub async fn execute(args: ConfigArgs, config_service: &dyn ConfigService) -> SubXResult<()> {
248 match args.action {
249 ConfigAction::Set { .. } => {
250 // TODO: Implement setting configuration values with ConfigService
251 return Err(SubXError::config(
252 "Setting configuration values not yet supported with ConfigService. Use config files or environment variables instead.",
253 ));
254 }
255 ConfigAction::Get { key } => {
256 let value = config_service.get_config_value(&key)?;
257 println!("{}", value);
258 }
259 ConfigAction::List => {
260 let config = config_service.get_config()?;
261 if let Ok(path) = config_service.get_config_file_path() {
262 println!("# Configuration file path: {}\n", path.display());
263 }
264 println!(
265 "{}",
266 toml::to_string_pretty(&config)
267 .map_err(|e| SubXError::config(format!("TOML serialization error: {}", e)))?
268 );
269 }
270 ConfigAction::Reset => {
271 config_service.reset_to_defaults()?;
272 println!("Configuration reset to default values");
273 if let Ok(path) = config_service.get_config_file_path() {
274 println!("Default configuration saved to: {}", path.display());
275 }
276 }
277 }
278 Ok(())
279}
280
281/// Execute configuration management command with injected configuration service.
282///
283/// This function provides the new dependency injection interface for the config command,
284/// accepting a configuration service instead of loading configuration globally.
285///
286/// # Arguments
287///
288/// * `args` - Configuration command arguments
289/// * `config_service` - Configuration service providing access to settings
290///
291/// # Returns
292///
293/// Returns `Ok(())` on successful completion, or an error if the operation fails.
294pub async fn execute_with_config(
295 args: ConfigArgs,
296 config_service: std::sync::Arc<dyn ConfigService>,
297) -> SubXResult<()> {
298 match args.action {
299 ConfigAction::Set { .. } => {
300 return Err(SubXError::config(
301 "Setting configuration values not yet supported with ConfigService. Use config files or environment variables instead.".to_string(),
302 ));
303 }
304 ConfigAction::Get { key } => {
305 let value = config_service.get_config_value(&key)?;
306 println!("{}", value);
307 }
308 ConfigAction::List => {
309 let config = config_service.get_config()?;
310 if let Ok(path) = config_service.get_config_file_path() {
311 println!("# Configuration file path: {}\n", path.display());
312 }
313 println!(
314 "{}",
315 toml::to_string_pretty(&config)
316 .map_err(|e| SubXError::config(format!("TOML serialization error: {}", e)))?
317 );
318 }
319 ConfigAction::Reset => {
320 config_service.reset_to_defaults()?;
321 println!("Configuration reset to default values");
322 if let Ok(path) = config_service.get_config_file_path() {
323 println!("Default configuration saved to: {}", path.display());
324 }
325 }
326 }
327 Ok(())
328}