use log::{error, info, warn};
use tokio::net::{TcpListener, TcpStream};
use anyhow::{Result as DynResult, Error};
use tokio::time::{sleep, Duration};
use std::{borrow::BorrowMut, net::{IpAddr, Ipv4Addr}};
// use std::io::BufReader;
use tokio::io::{BufReader, AsyncWriteExt, AsyncBufReadExt};


pub async fn init_cli_pipeline() -> DynResult<()> {
    return match init_listener().await {
        Some(list) => {
            loop {
                if let Ok((socket, addr)) = list.accept().await {
                    // isolation
                    if IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)) != addr.ip() {
                        warn!("Declined attempt to connect TCP-socket from {}", addr);
                        continue;
                    }
                    process_connection(socket).await;
                }
                sleep(Duration::from_millis(500)).await;
            }
            // Ok(())
        },
        None => Err(Error::msg("Addr 127.0.0.1:7753 is already in use"))
    }
}

async fn init_listener() -> Option<TcpListener> {
    return match TcpListener::bind("127.0.0.1:7753").await {
        Ok(listener) => {
            info!("Runner is listening localhost:7753");
            Some(listener)
        },
        Err(_) => {
            error!("Cannot create TCP listener for CLI");
            None
        } 
    }
}

async fn process_connection(mut stream: TcpStream) {
    // loop{
    //     stream.
    // }
    let buf_reader = BufReader::new(stream.borrow_mut());
    let mut rqst = buf_reader.lines();

    while let Ok(Some(line)) = rqst.next_line().await {
        if line.is_empty() {
            break;
        }
        println!("{}", line);
    }
        // .map(|result| result.unwrap())
        // .take_while(|line| !line.is_empty())
        // .collect();
    let response = "HTTP/1.1 200 OK\r\nContent-Length: 13\r\nContent-Type: text/plain\r\n\r\nHello, World!";
    stream.write_all(response.as_bytes()).await.unwrap();
}
