use log::*;
use trillium::Status;

pub fn fixup_paths() -> impl trillium::Handler {
    path_fixup_handler
}

async fn path_fixup_handler(mut conn: trillium::Conn) -> trillium::Conn {
    let parts = conn.path().split('/');
    let mut path = Vec::new();
    for part in parts {
        // empty: remove
        if part == "" || part == "." {
            continue;
        }
        // traverse
        if part == ".." {
            if path.is_empty() {
                return conn
                    .with_status(Status::BadRequest)
                    .with_body("invalid path")
                    .halt();
            } else {
                path.pop();
            }
        } else {
            path.push(part);
        }
    }

    let mut path = format!("/{}", path.join("/"));
    if conn.path().ends_with("/") && path != "/" {
        path += "/"
    }
    trace!("cleaned {} -> {}", conn.path(), path);
    conn.push_path(path);
    conn
}
