snipt_cli/
commands.rs

1use crate::cli::Commands;
2use crate::utils::display_main_ui;
3use crossterm::execute;
4use crossterm::terminal::{disable_raw_mode, LeaveAlternateScreen};
5use snipt_core::{add_snippet, delete_snippet, update_snippet, Result};
6use snipt_daemon::{daemon_status, daemon_worker_entry, start_daemon, stop_daemon};
7use snipt_server::server::http_server::{check_api_server_health, diagnose_api_server};
8use snipt_server::server::start_api_server;
9use snipt_server::server::utils::get_api_server_port;
10use snipt_ui::{display_snippet_manager, interactive_add, AddResult};
11use std::io::stdout;
12use std::thread;
13use std::time::Duration;
14
15pub fn handle_command(command: Option<Commands>) -> Result<()> {
16    match command {
17        Some(command) => handle_subcommand(command),
18        None => display_main_ui(), // Default: show main UI when no command provided
19    }
20}
21
22fn handle_subcommand(command: Commands) -> Result<()> {
23    match command {
24        Commands::Add { shortcut, snippet } => {
25            add_snippet(shortcut, snippet).map(|_| println!("Snippet added successfully"))
26        }
27        Commands::Delete { shortcut } => {
28            delete_snippet(&shortcut).map(|_| println!("Snippet deleted successfully"))
29        }
30        Commands::Update { shortcut, snippet } => {
31            update_snippet(&shortcut, snippet).map(|_| println!("Snippet updated successfully"))
32        }
33        Commands::Start { port } => start_daemon(port),
34        Commands::Stop => stop_daemon(),
35        Commands::Status => daemon_status(),
36        Commands::New => handle_interactive_add(),
37        Commands::List => display_snippet_manager(),
38        Commands::Serve { port } => handle_serve_command(port),
39        Commands::Port => handle_port_command(),
40        Commands::ApiStatus => check_api_server_health(),
41        Commands::ApiDiagnose => diagnose_api_server(),
42        Commands::DaemonWorker => daemon_worker_entry(),
43    }
44}
45
46fn handle_interactive_add() -> Result<()> {
47    // First, fully reset terminal state
48    let _ = disable_raw_mode();
49    let _ = execute!(stdout(), LeaveAlternateScreen);
50
51    // Clear the screen explicitly to prevent artifacts
52    println!("\x1B[2J\x1B[1;1H");
53
54    // Add the snippet interactively
55    let interactive_result = interactive_add();
56
57    // Reset terminal state again
58    let _ = disable_raw_mode();
59    let _ = execute!(stdout(), LeaveAlternateScreen);
60
61    // Clear the screen again
62    println!("\x1B[2J\x1B[1;1H");
63
64    match interactive_result {
65        AddResult::Added => {
66            thread::sleep(Duration::from_millis(300));
67            // Launch the snippet manager UI
68            if let Err(e) = display_snippet_manager() {
69                eprintln!("Error displaying snippets: {}", e);
70            }
71        }
72        AddResult::Cancelled => {
73            println!("Operation canceled.");
74            thread::sleep(Duration::from_millis(300));
75        }
76        AddResult::Error(e) => {
77            // Print the error but don't return it from main
78            eprintln!("Error: {}", e);
79            thread::sleep(Duration::from_millis(500));
80        }
81    }
82
83    // Regardless of what happened above, always return to main menu
84    // Start with a completely fresh terminal state
85    let _ = disable_raw_mode();
86    let _ = execute!(stdout(), LeaveAlternateScreen);
87    println!("\x1B[2J\x1B[1;1H");
88
89    display_main_ui()
90}
91
92fn handle_serve_command(port: u16) -> Result<()> {
93    // Start API server only in a properly configured runtime
94    let runtime = tokio::runtime::Builder::new_multi_thread()
95        .enable_all()
96        .build()
97        .unwrap();
98
99    // Block the current thread with the server
100    runtime.block_on(async {
101        println!("Starting standalone API server on port {}...", port);
102        start_api_server(port).await
103    })
104}
105
106fn handle_port_command() -> Result<()> {
107    match get_api_server_port() {
108        Ok(port) => {
109            println!("snipt API server is running on port {}", port);
110            println!("UI available at: http://localhost:{}", port);
111            Ok(())
112        }
113        Err(_) => {
114            println!("snipt API server port information not found.");
115            println!(
116                "The API server may not be running or was started without saving port information."
117            );
118            println!("Try 'snipt status' for more details.");
119            Ok(())
120        }
121    }
122}