use std::io::{BufRead, BufReader, Write}; use std::net::TcpStream; use std::sync::Mutex; use once_cell::sync::Lazy; use rusqlite::Connection; use crate::database; static DB_CONN: Lazy> = Lazy::new(|| Mutex::new(database::init_db())); pub fn handle_client(stream: TcpStream) { let client_addr = stream.peer_addr().unwrap().to_string(); let mut user = "guest".to_string(); println!("[{} @ {}] Client connected", user, client_addr); let reader_stream = stream.try_clone().unwrap(); let reader = BufReader::new(reader_stream); let mut writer = stream; for line in reader.lines() { let line = line.unwrap(); println!("[{} @ {}] Received: {}", user, client_addr, line); let response = process_message(&line, &mut user); writeln!(writer, "{}", response).unwrap(); println!("[{} @ {}] Sent: {}", user, client_addr, response); } println!("[{} @ {}] Client disconnected", user, client_addr); } fn process_message(msg: &str, user: &mut String) -> String { let parts: Vec<&str> = msg.splitn(3, ' ').collect(); match parts[0] { "REGISTER" => { if parts.len() != 3 { "ERROR Invalid REGISTER format".to_string() } else { let username = parts[1]; let hashed_password = parts[2]; let db = DB_CONN.lock().unwrap(); match database::add_user(&db, username, hashed_password) { Ok(_) => format!("REGISTERED {}", username), Err(_) => "ERROR User already exists".to_string(), } } } "AUTH" => { if parts.len() != 3 { "ERROR Invalid AUTH format".to_string() } else { let username = parts[1]; let sent_hash = parts[2]; let db = DB_CONN.lock().unwrap(); if let Some(stored_hash) = database::get_hashed_password(&db, username) { if sent_hash == stored_hash { *user = username.to_string(); format!("OK {}", username) } else { "ERROR Invalid credentials".to_string() } } else { "ERROR User not found".to_string() } } } "PING" => "PONG".to_string(), "INFO" => { if *user == "guest" { "ERROR Not logged in".to_string() } else { let db = DB_CONN.lock().unwrap(); if let (Some(id), Some(balance)) = (database::get_account_id(&db, user), database::get_balance(&db, user)) { format!("INFO {} {} {}", user, id, balance) } else { "ERROR Error retrieving user info".to_string() } } } _ => msg.to_string(), // Echo back for compatibility } }