1+ use std:: sync:: Arc ;
2+ use axum:: http:: StatusCode ;
3+ use axum:: Json ;
4+ use tokio:: spawn;
5+ use tokio:: sync:: Mutex ;
6+ use crate :: bot:: run_bot;
7+ use crate :: config:: load_config;
8+ use crate :: types:: { BotState , BotStatus } ;
9+
10+ pub enum StartBotResponse {
11+ Success ( StatusCode , Json < & ' static str > ) ,
12+ Conflict ( StatusCode , Json < & ' static str > ) ,
13+ }
14+
15+ pub enum StopBotResponse {
16+ Success ( StatusCode , Json < & ' static str > ) ,
17+ Conflict ( StatusCode , Json < & ' static str > ) ,
18+ }
19+
20+ pub async fn start_bot ( bot_state : Arc < Mutex < BotState > > ) -> StartBotResponse
21+ {
22+ let mut state_lock = bot_state. lock ( ) . await ;
23+ match state_lock. status {
24+ BotStatus :: Stopped => {
25+ state_lock. config = load_config ( "config.toml" ) ;
26+
27+ if state_lock. config . is_none ( ) {
28+ return StartBotResponse :: Conflict ( StatusCode :: BAD_REQUEST , Json ( "Missing configuration." ) ) ;
29+ }
30+
31+ let ( shutdown_tx, mut shutdown_rx) = tokio:: sync:: watch:: channel ( false ) ;
32+ let ( command_tx, command_rx) = tokio:: sync:: mpsc:: channel ( 32 ) ;
33+ let bot_state_clone = bot_state. clone ( ) ;
34+
35+ let handle = spawn ( async move {
36+ run_bot ( bot_state_clone. clone ( ) , & mut shutdown_rx, command_rx) . await ;
37+ let mut s = bot_state_clone. lock ( ) . await ;
38+ s. status = BotStatus :: Stopped ;
39+ } ) ;
40+ state_lock. status = BotStatus :: Running {
41+ handle,
42+ shutdown : shutdown_tx,
43+ } ;
44+ state_lock. command_tx = command_tx;
45+
46+ drop ( state_lock) ;
47+ StartBotResponse :: Success ( StatusCode :: OK , Json ( "Bot is starting" ) )
48+ }
49+ BotStatus :: Running { .. } => StartBotResponse :: Conflict ( StatusCode :: BAD_REQUEST , Json ( "Bot is already running" ) ) ,
50+ }
51+ }
52+
53+ pub async fn stop_bot ( bot_state : Arc < Mutex < BotState > > ) -> StopBotResponse {
54+ let handle_and_shutdown = {
55+ let mut state_lock = bot_state. lock ( ) . await ;
56+
57+ match std:: mem:: replace ( & mut state_lock. status , BotStatus :: Stopped ) {
58+ BotStatus :: Running { handle, shutdown } => Some ( ( handle, shutdown) ) ,
59+ BotStatus :: Stopped => None ,
60+ }
61+ } ;
62+
63+ if let Some ( ( handle, shutdown_tx) ) = handle_and_shutdown {
64+ let _ = shutdown_tx. send ( true ) ;
65+ handle. await . unwrap ( ) ;
66+ StopBotResponse :: Success ( StatusCode :: OK , Json ( "Bot stopped" ) )
67+ } else {
68+ println ! ( "Not Starting bot stop" ) ;
69+ StopBotResponse :: Conflict ( StatusCode :: CONFLICT , Json ( "Bot is not running" ) )
70+ }
71+ }
0 commit comments