use super::ProtocolConfig;

use std::io;
use std::net::Ipv6Addr;
use std::net::SocketAddr;
use std::net::UdpSocket;
use std::str::FromStr;
use std::thread;

pub fn start_autoconnect_server_async(cfg: &ProtocolConfig) -> io::Result<()> {
    let cfg = cfg.clone();

    let multi_sock = UdpSocket::bind((cfg.listen_addr.as_str(), cfg.port))?;

    multi_sock.join_multicast_v6(
        &Ipv6Addr::from_str(&cfg.autoconnect_multicastv6_addr).map_err(|_| {
            io::Error::new(
                io::ErrorKind::InvalidInput,
                "Configured IPv6 addr. is invalid.",
            )
        })?,
        0,
    )?;

    thread::spawn(move || {
        let mut buffer = vec![0u8; 8096];
        loop {
            match multi_sock.recv_from(&mut buffer) {
                Ok((pkg_size, sender)) => {
                    let _ = respond(&multi_sock, &buffer[0..pkg_size], &sender, &cfg);
                }
                Err(e) => {
                    println!("[Autoconnect] failed with : {:?}", e);
                    break;
                }
            }
        }
    });

    Ok(())
}

fn respond(
    sock: &UdpSocket,
    input: &[u8],
    sender: &SocketAddr,
    cfg: &ProtocolConfig,
) -> io::Result<()> {
    if input == b"TextureSync" {
        sock.send_to(&u16::to_be_bytes(cfg.port), sender)?;
        println!("[Autoconnect] Got request from : {}", sender);
    }

    Ok(())
}
