1use crate::config::Config;
4use crate::output::{render_output, OutputFormat};
5use crate::types::{NodeInfo, NodeList, OperationResult};
6use anyhow::Result;
7use clap::Subcommand;
8
9#[derive(Subcommand)]
10pub enum NodeCommands {
11 #[command(alias = "ls")]
13 List,
14 #[command(aliases = ["show", "details"])]
16 Info {
17 node_id: String,
19 },
20 Start,
22 #[command(aliases = ["kill", "terminate"])]
24 Stop,
25 #[command(aliases = ["new", "add"])]
27 Create {
28 #[arg(short, long, default_value = "edge")]
30 role: String,
31 },
32 #[command(alias = "connect")]
34 Join {
35 address: String,
37 },
38 #[command(aliases = ["disconnect", "depart"])]
40 Leave,
41 #[command(aliases = ["cfg", "configure"])]
43 Config {
44 key: Option<String>,
46 value: Option<String>,
48 #[arg(short, long)]
50 all: bool,
51 },
52}
53
54pub async fn handle_node_command(action: NodeCommands, format: OutputFormat) -> Result<()> {
55 match action {
56 NodeCommands::List => {
57 let data = mock_node_list();
58 println!("{}", render_output(&data, format)?);
59 }
60 NodeCommands::Info { node_id } => {
61 let result = OperationResult {
62 success: true,
63 message: format!("Node info for {}", node_id),
64 id: Some(node_id),
65 };
66 println!("{}", render_output(&result, format)?);
67 }
68 NodeCommands::Start => {
69 let result = OperationResult {
70 success: true,
71 message: "Node started successfully".to_string(),
72 id: None,
73 };
74 println!("{}", render_output(&result, format)?);
75 }
76 NodeCommands::Stop => {
77 let result = OperationResult {
78 success: true,
79 message: "Node stopped successfully".to_string(),
80 id: None,
81 };
82 println!("{}", render_output(&result, format)?);
83 }
84 NodeCommands::Create { role } => {
85 let result = OperationResult {
86 success: true,
87 message: format!("Created {} node", role),
88 id: Some("new-node-uuid".to_string()),
89 };
90 println!("{}", render_output(&result, format)?);
91 }
92 NodeCommands::Join { address } => {
93 let result = OperationResult {
94 success: true,
95 message: format!("Joined cluster at {}", address),
96 id: None,
97 };
98 println!("{}", render_output(&result, format)?);
99 }
100 NodeCommands::Leave => {
101 let result = OperationResult {
102 success: true,
103 message: "Left cluster gracefully".to_string(),
104 id: None,
105 };
106 println!("{}", render_output(&result, format)?);
107 }
108 NodeCommands::Config { key, value, all } => {
109 let mut config = Config::load()?;
110
111 if all {
112 let config_str = toml::to_string_pretty(&config)?;
113 println!("{}", config_str);
114 } else if let Some(k) = key {
115 if let Some(v) = value {
116 config.set(&k, &v)?;
117 config.save()?;
118 let result = OperationResult {
119 success: true,
120 message: format!("Set {} = {}", k, v),
121 id: None,
122 };
123 println!("{}", render_output(&result, format)?);
124 } else if let Some(current_value) = config.get(&k) {
125 println!("{} = {}", k, current_value);
126 } else {
127 let result = OperationResult {
128 success: false,
129 message: format!("Unknown configuration key: {}", k),
130 id: None,
131 };
132 println!("{}", render_output(&result, format)?);
133 }
134 } else {
135 let result = OperationResult {
136 success: false,
137 message: "Please specify a configuration key or use --all".to_string(),
138 id: None,
139 };
140 println!("{}", render_output(&result, format)?);
141 }
142 }
143 }
144 Ok(())
145}
146
147fn mock_node_list() -> NodeList {
148 NodeList {
149 nodes: vec![
150 NodeInfo {
151 id: "a1b2c3d4-e5f6-7890-abcd-ef1234567890".to_string(),
152 role: "Core".to_string(),
153 state: "Running".to_string(),
154 address: "192.168.1.100:9000".to_string(),
155 agents: 5,
156 uptime: "3d 2h".to_string(),
157 version: "0.0.1".to_string(),
158 },
159 NodeInfo {
160 id: "b2c3d4e5-f6a7-8901-bcde-f12345678901".to_string(),
161 role: "Edge".to_string(),
162 state: "Running".to_string(),
163 address: "192.168.1.101:9000".to_string(),
164 agents: 2,
165 uptime: "1d 5h".to_string(),
166 version: "0.0.1".to_string(),
167 },
168 ],
169 total: 2,
170 }
171}