cstats-cli 0.1.1

Command line interface for cstats
//! Config command implementation

use std::io::{self, Write};

use cstats_core::{api::types::AnthropicConfig, config::Config, Result};
use tracing::info;

use crate::{ConfigAction, ConfigArgs, OutputFormat};

use super::print_output;

/// Manage configuration
pub async fn config_command(
    args: ConfigArgs,
    config: &Config,
    format: OutputFormat,
    config_path: Option<&std::path::Path>,
) -> Result<()> {
    match args.action {
        ConfigAction::Show => {
            info!("Showing current configuration");

            // Show config source info first
            println!("Configuration loaded from:");
            if std::env::var("ANTHROPIC_API_KEY").is_ok() {
                println!("  ✓ ANTHROPIC_API_KEY environment variable");
            }

            if let Some(path) = config_path {
                if path.exists() {
                    println!("  ✓ Config file: {}", path.display());
                } else {
                    println!("  ⚠ Specified config file not found: {}", path.display());
                }
            } else if let Ok(default_path) = Config::default_config_path() {
                if default_path.exists() {
                    println!("  ✓ Config file: {}", default_path.display());
                } else {
                    println!("  ⚠ No config file found (using defaults)");
                }
            }

            println!();
            print_output(config, format)?;
        }

        ConfigAction::Validate => {
            info!("Validating configuration");

            match config.validate() {
                Ok(()) => {
                    println!("✓ Configuration is valid");

                    // Additional checks and info
                    if config.has_anthropic_api_key() {
                        println!("✓ Anthropic API key is configured");
                    } else {
                        println!("⚠ Anthropic API key is not configured");
                        println!(
                            "  Set ANTHROPIC_API_KEY environment variable or run 'cstats init'"
                        );
                    }

                    // Show config file location
                    if let Some(path) = config_path {
                        if path.exists() {
                            println!("✓ Config file found at: {}", path.display());
                        } else {
                            println!("⚠ Specified config file not found: {}", path.display());
                        }
                    } else if let Ok(default_path) = Config::default_config_path() {
                        if default_path.exists() {
                            println!("✓ Config file found at: {}", default_path.display());
                        } else {
                            println!(
                                "⚠ No config file found at default location: {}",
                                default_path.display()
                            );
                            println!("  Run 'cstats init' to create one");
                        }
                    }
                }
                Err(e) => {
                    println!("✗ Configuration validation failed:");
                    println!("{}", e);
                    return Err(e);
                }
            }
        }

        ConfigAction::Default => {
            info!("Generating default configuration");
            let default_config = Config::default();
            print_output(&default_config, format)?;
        }

        ConfigAction::SetApiKey { api_key } => {
            info!("Setting Anthropic API key");

            let key = if let Some(key) = api_key {
                key.clone()
            } else {
                prompt_for_api_key()?
                    .ok_or_else(|| cstats_core::Error::config("API key is required"))?
            };

            // Load existing config or create default
            let config_path = Config::default_config_path()?;
            let mut config = if config_path.exists() {
                Config::load_from_file(&config_path).await?
            } else {
                Config::default()
            };

            // Set the API key
            let anthropic_config = AnthropicConfig {
                api_key: key,
                ..config.api.anthropic.unwrap_or_default()
            };
            config.api.anthropic = Some(anthropic_config);

            // Save the config
            config.save_to_file(&config_path).await?;

            println!("✓ Anthropic API key saved to: {}", config_path.display());
            println!("You can now run 'cstats stats' to fetch usage statistics");
        }
    }

    Ok(())
}

/// Prompt user for Anthropic API key
fn prompt_for_api_key() -> Result<Option<String>> {
    print!("Enter your Anthropic API key: ");
    io::stdout().flush().map_err(cstats_core::Error::from)?;

    let mut input = String::new();
    io::stdin()
        .read_line(&mut input)
        .map_err(cstats_core::Error::from)?;

    let api_key = input.trim().to_string();

    if api_key.is_empty() {
        Ok(None)
    } else if api_key.starts_with("sk-ant-") {
        Ok(Some(api_key))
    } else {
        println!("⚠ Warning: API key doesn't match expected format (should start with 'sk-ant-')");
        print!("Use anyway? (y/N): ");
        io::stdout().flush().map_err(cstats_core::Error::from)?;

        let mut confirm = String::new();
        io::stdin()
            .read_line(&mut confirm)
            .map_err(cstats_core::Error::from)?;

        if confirm.trim().to_lowercase() == "y" {
            Ok(Some(api_key))
        } else {
            Ok(None)
        }
    }
}