1use crate::cli::args::ConfigAction;
2use crate::system::{get_config_path, load_config, load_default_config, save_config};
3use anyhow::Result;
4use std::{fmt::Display, str::FromStr};
5
6pub fn handle_config_command(action: Option<ConfigAction>) -> Result<()> {
7 let action = action.unwrap_or(ConfigAction::Show);
8
9 match action {
10 ConfigAction::Show => {
11 let config_path = get_config_path()?;
12 let config = load_config()?;
13 let toml_str = toml::to_string_pretty(&config)
14 .map_err(|e| anyhow::anyhow!("Failed to serialize config to TOML: {}", e))?;
15 println!("Config file location: {}\n", config_path.display());
16 println!("{}", toml_str);
17 Ok(())
18 }
19 ConfigAction::Reset => {
20 let default_config = load_default_config()?;
21 save_config(&default_config)?;
22 println!("✅ Configuration reset to default");
23 Ok(())
24 }
25 ConfigAction::Set { key, value } => {
26 set_value(&key, &value)?;
27 println!("✅ Config {} = {}", key, value);
28 Ok(())
29 }
30 ConfigAction::Get { key } => {
31 let value = get_value(&key)?;
32 println!("{}", value);
33 Ok(())
34 }
35 ConfigAction::Unset { key } => {
36 unset_value(&key)?;
37 println!("✅ Config {} reset to default", key);
38 Ok(())
39 }
40 }
41}
42
43fn get_value(key: &str) -> Result<String> {
44 let config = load_config()?;
45
46 let value = match key {
47 "llm.provider" => config.llm.provider.as_str().to_string(),
48 "llm.model" => config.llm.model,
49 "llm.timeout" => config.llm.timeout.to_string(),
50 "llm.use_thinking" => config.llm.use_thinking.to_string(),
51 "llm.use_web_search" => config.llm.use_web_search.to_string(),
52 "context.max_lines" => config.context.max_lines.to_string(),
53 "context.max_size_kb" => config.context.max_size_kb.to_string(),
54 "logging.enabled" => config.logging.enabled.to_string(),
55 "logging.level" => config.logging.level,
56 _ => anyhow::bail!("Unknown config key: {}", key),
57 };
58
59 Ok(value)
60}
61
62fn set_value(key: &str, value: &str) -> Result<()> {
63 let mut config = load_config()?;
64
65 match key {
66 "llm.provider" => {
67 config.llm.provider = value.parse()?;
68 }
69 "llm.model" => {
70 config.llm.model = value.to_string();
71 }
72 "llm.timeout" => {
73 config.llm.timeout = parse_value(value, "timeout")?;
74 }
75 "llm.use_thinking" => {
76 config.llm.use_thinking = parse_value(value, "use_thinking")?;
77 }
78 "llm.use_web_search" => {
79 config.llm.use_web_search = parse_value(value, "use_web_search")?;
80 }
81 "context.max_lines" => {
82 config.context.max_lines = parse_value(value, "max_lines")?;
83 }
84 "context.max_size_kb" => {
85 config.context.max_size_kb = parse_value(value, "max_size_kb")?;
86 }
87 "logging.enabled" => {
88 config.logging.enabled = parse_value(value, "logging.enabled")?;
89 }
90 "logging.level" => {
91 config.logging.level = value.to_string();
92 }
93 _ => anyhow::bail!("Unknown config key: {}", key),
94 }
95
96 save_config(&config)?;
97 Ok(())
98}
99
100fn unset_value(key: &str) -> Result<()> {
101 let default_config = load_default_config()?;
102 let mut config = load_config()?;
103
104 match key {
105 "llm.provider" => config.llm.provider = default_config.llm.provider,
106 "llm.model" => config.llm.model = default_config.llm.model,
107 "llm.timeout" => config.llm.timeout = default_config.llm.timeout,
108 "llm.use_thinking" => config.llm.use_thinking = default_config.llm.use_thinking,
109 "llm.use_web_search" => config.llm.use_web_search = default_config.llm.use_web_search,
110 "context.max_lines" => config.context.max_lines = default_config.context.max_lines,
111 "context.max_size_kb" => config.context.max_size_kb = default_config.context.max_size_kb,
112 "logging.enabled" => config.logging.enabled = default_config.logging.enabled,
113 "logging.level" => config.logging.level = default_config.logging.level,
114 _ => anyhow::bail!("Unknown config key: {}", key),
115 }
116
117 save_config(&config)?;
118 Ok(())
119}
120
121fn parse_value<T: FromStr>(value: &str, field_name: &str) -> Result<T>
122where
123 T::Err: Display,
124{
125 value
126 .parse()
127 .map_err(|e| anyhow::anyhow!("Invalid {} value: {} - {}", field_name, value, e))
128}