use std::{io, collections::HashMap, env::args, os::unix::fs::MetadataExt};
use bytes::BytesMut;
use tokio::{net::{TcpListener, TcpStream}, io::{AsyncReadExt, AsyncWriteExt}, fs::File};


use itertools::Itertools;
use nom::AsChar;

#[derive(Debug)]
enum BodyTypes {
    File(File),
    String(String)
}

#[derive(PartialEq)]
enum RequestSection {
    RequestLine,
    Headers,
    Body
}

async fn process_socket(mut stream: TcpStream) -> Result<(), &'static str> {
    println!("accepted new connection");
    let mut request: HashMap<String, String> = HashMap::new();
    let mut section: RequestSection = RequestSection::RequestLine;
    loop {
        let mut line = String::default();

        if section == RequestSection::Body {
            let content_size: usize = request.get("Content-Length").unwrap().parse::<usize>().unwrap();
            let mut buf: Vec<u8> = vec![0; content_size];
            stream.read_exact(&mut buf).await.unwrap();
        } else {
            loop {
                let mut buf: [u8; 1] = [0; 1];
                stream.read_exact(&mut buf).await.unwrap();

                let character = buf[0].as_char();

                if character == '\n' {
                    break
                } else if character != '\r' {
                    line.push(character);
                }
            }
        }

        match section {
            RequestSection::RequestLine => {
                let mut splits = line.split(' ');
                request.insert("method".to_owned(), splits.next().unwrap().to_owned());
                request.insert("path".to_owned(), splits.next().unwrap().to_owned());
                
                section = RequestSection::Headers;
            }
            RequestSection::Headers => {
                if line == "" {
                    section = RequestSection::Body;
                } else {
                    let mut splits = line.split(":");
                    let key = splits.next().unwrap();
                    let value = splits.next().unwrap_or_default().trim();
                    request.insert(key.to_owned(), value.to_owned());
                }
            },
            RequestSection::Body => {
                request.insert("body".to_owned(), line);
                break;
            },
        }

        if request.get("path").unwrap() == "/user-agent" && !request.contains_key("User-Agent") { continue; };
        if request.get("path").unwrap().starts_with("/files/") && request.get("method").unwrap() == "POST" && !request.contains_key("body") { continue; };
        break;
    }

    let mut path = request.get("path").unwrap().split("/");

    let response_status: String;
    let mut response_headers: Vec<String> = vec![];
    let response_body: BodyTypes;

    path.next().unwrap();

    match path.next().unwrap() {
        "" => {
            response_status = "200 OK".into();
            response_body = BodyTypes::String("".into());
        },
        "echo" => {
            response_status = "200 OK".into();
            response_body = BodyTypes::String(path.join("/"));
            response_headers.push("Content-Type: text/plain".into());
        },
        "user-agent" => {
            response_status = "200 OK".into();
            response_body = BodyTypes::String(request.get("User-Agent").unwrap().into());
            response_headers.push("Content-Type: text/plain".into());
        },
        "files" => {
            let args: Vec<String> = args().collect();
            let dir_arg = args.iter().find_position(|item| **item == "--directory");
            let file_name = path.join("/");
            let file_path = if dir_arg.is_some() {
                args[dir_arg.unwrap().0+1].to_owned() + "/" + file_name.as_str()
            } else {
                return Err("No directory Given".into())
            };
            match request.get("method").unwrap().as_str() {
                "GET" => {
                    let maybe_file = File::open(file_path).await;
                    match maybe_file {
                        Ok(file) => {
                            response_status = "200 OK".into();
                            response_body = BodyTypes::File(file);
                            response_headers.push("Content-Type: application/octet-stream".into());
                        },
                        Err(_) => {
                            response_status = "404 Not Found".into();
                            response_body = BodyTypes::String("".into());
                        }
                    }
                },
                "POST" => {
                    let file = File::create(file_path).await;
                    match file {
                        Ok(mut f) => {
                            f.write(request.get("body").unwrap().as_bytes()).await.unwrap();
                            response_status = "201 Created".into();
                            response_body = BodyTypes::String("".into());
                        },
                        Err(_) => {
                            response_body = BodyTypes::String("500 INTERNAL SERVER ERROR".into());
                            response_status = "".into()
                        }
                    }
                },
                _ => unreachable!() // not actually unreachable, but please don't kill our server thank you with pretty puppies on top <3
            }
        },
        _ => {
            response_status = "404 Not Found".into();
            response_body = BodyTypes::String("".into());
        }
    }

    match response_body {
        BodyTypes::String(ref content) => {
            response_headers.push(format!("Content-Length: {}", content.len()));
        },
        BodyTypes::File(ref file) => {
            response_headers.push(format!("Content-Length: {}", file.metadata().await.unwrap().size()));
        }
    }

    stream.write(format!("HTTP/1.1 {response_status}\r\n{}\r\n\r\n", response_headers.join("\r\n")).as_bytes()).await.unwrap();

    match response_body {
        BodyTypes::String(ref content) => {
            stream.write(content.as_bytes()).await.unwrap();
        },
        BodyTypes::File(mut file) => {
            loop {
                let mut buf = BytesMut::with_capacity(1024);

                let read = file.read_buf(&mut buf).await.unwrap();

                if read == 0 {
                    break;
                }

                stream.write(&mut buf).await.unwrap();
            }
        }
    }

    Ok(())
}

#[tokio::main]
async fn main() -> io::Result<()> {
    let listener = TcpListener::bind("127.0.0.1:4221").await?;
    let mut futures = vec![];

    loop {
        let (socket, _) = listener.accept().await?;
        futures.push(tokio::spawn(process_socket(socket)));
    }
}
