use std::path::PathBuf;

use http::handling::{
    file_handlers::NamedFile,
    methods::Method,
    request::Request,
    response::{Outcome, Response, ResponseBody, Status},
    routes::{Data, Route},
};

fn handler(request: Request, _data: Data) -> Outcome<Response, Status, Data> {
    let response = fileserver(request.uri.strip_prefix("static/").unwrap());
    let response = match response {
        Ok(dat) => Response {
            headers: vec![
                format!("Content-Length: {}", dat.get_len()),
                format!("Content-Type: {}", dat.get_mime()),
            ],
            status: Some(Status::Ok),
            body: Box::new(dat),
        },
        Err(_) => return Outcome::Failure(Status::NotFound),
    };
    Outcome::Success(response)
}

fn fileserver(path: &str) -> Result<NamedFile, Status> {
    NamedFile::open(PathBuf::from("static/".to_string() + path))
}

fn post_hi_handler(_request: Request, data: Data) -> Outcome<Response, Status, Data> {
    if data.is_empty() {
        return Outcome::Forward(data);
    }
    let data = if let Ok(str) = String::from_utf8(data.buffer) {
        str
    } else {
        return Outcome::Failure(Status::BadRequest);
    };
    let dat = post_hi(data);
    Outcome::Success(Response {
        headers: vec![
            format!("Content-Length: {}", dat.len()),
            format!("Content-Type: text/plain"),
        ],
        status: Some(Status::Ok),
        body: Box::new(dat),
    })
}

fn post_hi(msg: String) -> String {
    msg
}

fn main() {
    let fileserver = Route {
        format: None,
        handler,
        name: Some("file_server"),
        uri: "static/<path..>",
        method: Method::Get,
        rank: 0,
    };

    let post_test = Route {
        format: None,
        handler: post_hi_handler,
        name: Some("post_test"),
        uri: "post",
        method: Method::Post,
        rank: 0,
    };

    http::build("127.0.0.1:8000")
        .mount("/", vec![fileserver, post_test])
        .launch();
}