<commit_before>// <NAME>
// <NAME>
// <NAME>
// <NAME>

use std::collections::HashMap;
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, TryRecvError};
use std::thread;

use message::Message;

mod message;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
    let usernames = Arc::new(Mutex::new(HashMap::new()));
    let (sender_to_router, receiver_from_clients) = channel();

    //Router thread
    thread::spawn(move|| {
        loop {
            // TODO: use recv or try_recv here?
            let msg: Message = receiver_from_clients.recv().unwrap();
            println!("Router received message date {}, from {}, to {}, content {}", 
                msg.date(), msg.from(), msg.to(), msg.content());
            // TODO: lookup recipient in hashmap and forward msg.content
        }
    });

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let usernames = usernames.clone();
                let sender_to_router = sender_to_router.clone();
                thread::spawn(move|| {
                    // connection succeeded
                    handle_client(stream, sender_to_router, &usernames);
                });
            }
            Err(e) => {
                println!("{}", e);
            }
        }
    }

    // close the socket server
    drop(listener);
}

fn handle_client(stream: TcpStream, sender_to_router: Sender<Message>, usernames: &Arc<Mutex<HashMap<String, Sender<Message>>>>) {
    println!("New client");
    let mut stream = stream;
    stream.write(&"Welcome to Smazy\n".to_string().into_bytes()).unwrap();
    stream.write(&"Please enter a username:\n".to_string().into_bytes()).unwrap();
    stream.flush().unwrap();
    let mut reader = BufReader::new(stream);
    let mut username = "".to_string();
    match reader.read_line(&mut username) {
        Ok(n) => {
            let (sender_to_client, receiver_from_router) = channel();
            let mut guard = usernames.lock().unwrap();
            if n > 0 && !guard.contains_key(&username) {
                guard.insert(username.to_string(), sender_to_client);
                println!("Username is {}", username.to_string());
            }

            // TODO: show list of available to users and choose who to chat with
            // Include bool in hashmap for available?

            loop {
                let msg = Message::new("Date".to_string(), username.to_string(), "b".to_string(), "Hi".to_string());
                sender_to_router.send(msg).unwrap();
                match receiver_from_router.try_recv() {
                    Ok(msg) => println!("User {} received message: {}", &username, msg.content()),
                    Err(TryRecvError::Empty) => continue,
                    Err(TryRecvError::Disconnected) => panic!("User {} disconnected from router", &username)
                }
            }
        },
        Err(e) => println!("{}", e)
    }
}<commit_msg>Attempt to send messages from router to user B<commit_after>// <NAME>
// <NAME>
// <NAME>
// <NAME>

use std::collections::HashMap;
use std::io::{BufRead, BufReader, Write};
use std::net::{TcpListener, TcpStream};
use std::sync::{Arc, Mutex};
use std::sync::mpsc::{channel, Sender, TryRecvError};
use std::thread;

use message::Message;

mod message;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
    let usernames = Arc::new(Mutex::new(HashMap::new()));
    let (sender_to_router, receiver_from_clients) = channel();

    //Router thread
    let usernames_clone = usernames.clone();
    thread::spawn(move|| {
        loop {
            // TODO: use recv or try_recv here?
            let msg: Message = receiver_from_clients.recv().unwrap();
            println!("Router received message date {}, from {}, to {}, content {}", 
                msg.date(), msg.from(), msg.to(), msg.content());
            let sender : &Sender<Message> = usernames_clone.lock().unwrap().get(msg.to()).unwrap();
            sender.send(msg).unwrap();
            // TODO: lookup recipient in hashmap and forward msg.content
        }
    });

    // accept connections and process them, spawning a new thread for each one
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                let usernames = usernames.clone();
                let sender_to_router = sender_to_router.clone();
                thread::spawn(move|| {
                    // connection succeeded
                    handle_client(stream, sender_to_router, &usernames);
                });
            }
            Err(e) => {
                println!("{}", e);
            }
        }
    }

    // close the socket server
    drop(listener);
}

fn handle_client(stream: TcpStream, sender_to_router: Sender<Message>, usernames: &Arc<Mutex<HashMap<String, Sender<Message>>>>) {
    println!("New client");
    let mut stream = stream;
    stream.write(&"Welcome to Smazy\n".to_string().into_bytes()).unwrap();
    stream.write(&"Please enter a username:\n".to_string().into_bytes()).unwrap();
    stream.flush().unwrap();
    let mut reader = BufReader::new(stream);
    let mut username = "".to_string();
    match reader.read_line(&mut username) {
        Ok(n) => {
            let (sender_to_client, receiver_from_router) = channel();
            let mut guard = usernames.lock().unwrap();
            if n > 0 && !guard.contains_key(&username) {
                guard.insert(username.to_string(), sender_to_client);
                println!("Username is {}", username.to_string());
            }

            // TODO: show list of available to users and choose who to chat with
            // Include bool in hashmap for available?
            let username_clone = username.clone();
            thread::spawn(move|| { 


                let mut lines = BufReader::new(reader).lines(); 
                while let Some(Ok(line)) = lines.next() {
                    println!("{}",line);
                    let msg = Message::new("Date".to_string(), username_clone.to_string(), "b".to_string(), line.to_string());
                    sender_to_router.send(msg).unwrap();
                }

                
            });



            loop {
                
                match receiver_from_router.try_recv() {
                    Ok(msg) => println!("User {} received message: {}", &username, msg.content()),
                    Err(TryRecvError::Empty) => continue,
                    Err(TryRecvError::Disconnected) => panic!("User {} disconnected from router", &username)
                }
            }
        },
        Err(e) => println!("{}", e)
    }
}
{'fraction_non_alphanumeric': 0.14986137458047571, 'fraction_numerical': 0.0032102728731942215, 'mean_word_length': 2.152713891444342, 'pattern_counts': {'":': 0, '<': 22, '<?xml version=': 0, '>': 38, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5120649', 'n_tokens_mistral': 1949, 'n_tokens_neox': 1925, 'n_words': 445}