use std::{collections::HashSet, fs::metadata, os::unix::fs::MetadataExt};

fn main() {
    let path = if let Some(path) = std::env::args().nth(1) {
        path
    } else {
        std::env::var("PATH").expect("get PATH from environment")
    };
    println!("{}", pathdedup(&path));
}

fn pathdedup(path: &str) -> String {
    let mut elements: Vec<&str> = vec![];
    let mut seen: HashSet<(u64, u64)> = HashSet::new();

    for e in path.split(':') {
        if !elements.contains(&e) {
            if let Ok(meta) = metadata(e) {
                let key = (meta.dev(), meta.ino());
                if !seen.contains(&key) {
                    seen.insert(key);
                    elements.push(e);
                }
            } else {
                elements.push(e);
            }
        }
    }

    elements.join(":")
}

#[cfg(test)]
mod test {
    use super::pathdedup;

    #[test]
    fn empty_string() {
        assert_eq!(pathdedup(""), "");
    }

    #[test]
    fn single_element() {
        assert_eq!(pathdedup("/foo"), "/foo");
    }

    #[test]
    fn duplicate_elements() {
        assert_eq!(pathdedup("/foo:/foo"), "/foo");
    }
}
