Skip to main content

gromnie_cli/wizards/
config.rs

1use ratatui::Frame;
2use std::error::Error;
3
4use gromnie_client::config::GromnieConfig;
5
6use crate::app::App;
7use crate::draw::Draw;
8
9#[derive(Debug, Clone, PartialEq)]
10pub enum ConfigWizardStage {
11    Welcome,
12    EnteringServerName,
13    EnteringServerHost,
14    EnteringServerPort,
15    EnteringAccountUsername,
16    EnteringAccountPassword,
17    EnteringCharacterName,
18    Confirming,
19    Complete,
20}
21
22#[derive(Clone)]
23pub struct ConfigWizard {
24    pub stage: ConfigWizardStage,
25    pub server_name: String,
26    pub server_host: String,
27    pub server_port: String,
28    pub account_username: String,
29    pub account_password: String,
30    pub character_name: String,
31    pub current_input: String,
32}
33
34impl Default for ConfigWizard {
35    fn default() -> Self {
36        Self::new()
37    }
38}
39
40impl ConfigWizard {
41    pub fn new() -> Self {
42        Self {
43            stage: ConfigWizardStage::Welcome,
44            server_name: String::new(),
45            server_host: String::new(),
46            server_port: String::new(),
47            account_username: String::new(),
48            account_password: String::new(),
49            character_name: String::new(),
50            current_input: String::new(),
51        }
52    }
53
54    pub fn to_config(&self) -> GromnieConfig {
55        use std::collections::BTreeMap;
56
57        let mut servers = BTreeMap::new();
58        servers.insert(
59            self.server_name.clone(),
60            gromnie_client::config::ServerConfig {
61                host: self.server_host.clone(),
62                port: self.server_port.parse().unwrap_or(9000),
63            },
64        );
65
66        let mut accounts = BTreeMap::new();
67        // Note: character_name is collected but no longer stored in AccountConfig
68        // Auto-login is now handled by the scripting system (auto_login script)
69        accounts.insert(
70            self.account_username.clone(),
71            gromnie_client::config::AccountConfig {
72                username: self.account_username.clone(),
73                password: self.account_password.clone(),
74                character: None,
75            },
76        );
77
78        GromnieConfig {
79            servers,
80            accounts,
81            scripting: Default::default(),
82            reconnect: false,
83        }
84    }
85}
86
87impl Draw for ConfigWizard {
88    fn draw(self, _app: &mut App, frame: &mut Frame) -> Result<(), Box<dyn Error>> {
89        use ratatui::text::{Line, Text};
90        use ratatui::widgets::Paragraph;
91
92        let mut lines = Vec::new();
93
94        // Always show welcome
95        lines.push(Line::from("Welcome to Gromnie!"));
96        lines.push(Line::from(""));
97
98        match self.stage {
99            ConfigWizardStage::Welcome => {
100                lines.push(Line::from("No configuration file was found so the following prompts will help you create one."));
101                lines.push(Line::from(""));
102            }
103            _ => {
104                lines.push(Line::from("No configuration file was found so the following prompts will help you create one."));
105                lines.push(Line::from(""));
106
107                // Show completed server name if we've moved past it
108                if self.stage != ConfigWizardStage::EnteringServerName {
109                    lines.push(Line::from("  Server Name"));
110                    lines.push(Line::from(format!("  {}", self.server_name)));
111                    lines.push(Line::from(""));
112                }
113
114                // Show server name input if we're on that stage
115                if self.stage == ConfigWizardStage::EnteringServerName {
116                    lines.push(Line::from(format!(
117                        "  Enter a server name: {}█",
118                        self.current_input
119                    )));
120                    lines.push(Line::from(""));
121                }
122
123                // Show completed server host if we've moved past it
124                if matches!(
125                    self.stage,
126                    ConfigWizardStage::EnteringServerPort
127                        | ConfigWizardStage::EnteringAccountUsername
128                        | ConfigWizardStage::EnteringAccountPassword
129                        | ConfigWizardStage::Confirming
130                        | ConfigWizardStage::Complete
131                ) {
132                    lines.push(Line::from("  Hostname"));
133                    lines.push(Line::from(format!("  {}", self.server_host)));
134                    lines.push(Line::from(""));
135                }
136
137                // Show server host input if we're on that stage
138                if self.stage == ConfigWizardStage::EnteringServerHost {
139                    lines.push(Line::from(format!(
140                        "  Enter a hostname: {}█",
141                        self.current_input
142                    )));
143                    lines.push(Line::from(""));
144                }
145
146                // Show completed port if we've moved past it
147                if matches!(
148                    self.stage,
149                    ConfigWizardStage::EnteringAccountUsername
150                        | ConfigWizardStage::EnteringAccountPassword
151                        | ConfigWizardStage::Confirming
152                        | ConfigWizardStage::Complete
153                ) {
154                    lines.push(Line::from("  Port"));
155                    lines.push(Line::from(format!("  {}", self.server_port)));
156                    lines.push(Line::from(""));
157                }
158
159                // Show port input if we're on that stage
160                if self.stage == ConfigWizardStage::EnteringServerPort {
161                    lines.push(Line::from(format!(
162                        "  Enter a port (default: 9000): {}█",
163                        self.current_input
164                    )));
165                    lines.push(Line::from(""));
166                }
167
168                // Show completed account username if we've moved past it
169                if matches!(
170                    self.stage,
171                    ConfigWizardStage::EnteringAccountPassword
172                        | ConfigWizardStage::Confirming
173                        | ConfigWizardStage::Complete
174                ) {
175                    lines.push(Line::from("  Account"));
176                    lines.push(Line::from(format!("  {}", self.account_username)));
177                    lines.push(Line::from(""));
178                }
179
180                // Show username input if we're on that stage
181                if self.stage == ConfigWizardStage::EnteringAccountUsername {
182                    lines.push(Line::from(format!(
183                        "  Enter account name: {}█",
184                        self.current_input
185                    )));
186                    lines.push(Line::from(""));
187                }
188
189                // Show completed password if we've moved past it
190                if matches!(
191                    self.stage,
192                    ConfigWizardStage::EnteringCharacterName
193                        | ConfigWizardStage::Confirming
194                        | ConfigWizardStage::Complete
195                ) {
196                    lines.push(Line::from("  Password"));
197                    lines.push(Line::from(format!(
198                        "  {}",
199                        "*".repeat(self.account_password.len())
200                    )));
201                    lines.push(Line::from(""));
202                }
203
204                // Show password input if we're on that stage
205                if self.stage == ConfigWizardStage::EnteringAccountPassword {
206                    lines.push(Line::from(format!(
207                        "  Enter a password: {}█",
208                        "*".repeat(self.current_input.len())
209                    )));
210                    lines.push(Line::from(""));
211                }
212
213                // Show completed character name if we've moved past it
214                if matches!(
215                    self.stage,
216                    ConfigWizardStage::Confirming | ConfigWizardStage::Complete
217                ) {
218                    let char_display = if self.character_name.is_empty() {
219                        "(not specified)".to_string()
220                    } else {
221                        self.character_name.clone()
222                    };
223                    lines.push(Line::from("  Character"));
224                    lines.push(Line::from(format!("  {}", char_display)));
225                    lines.push(Line::from(""));
226                }
227
228                // Show character name input if we're on that stage
229                if self.stage == ConfigWizardStage::EnteringCharacterName {
230                    lines.push(Line::from(format!(
231                        "  Enter character name (* for any, leave empty to skip): {}█",
232                        self.current_input
233                    )));
234                    lines.push(Line::from(""));
235                }
236
237                // Show confirmation prompt
238                if self.stage == ConfigWizardStage::Confirming {
239                    lines.push(Line::from(
240                        "? Configuration complete. Press <enter> to save",
241                    ));
242                }
243            }
244        }
245
246        let text = Text::from(lines);
247        let paragraph = Paragraph::new(text);
248        frame.render_widget(paragraph, frame.area());
249
250        Ok(())
251    }
252}