use treehouse::vfs::{
    entries, query, BufferedFile, Cd, Content, MemDir, ToDynDir, VPath, VPathBuf,
};

const HEWWO: &[u8] = b"hewwo :3";
const FWOOFEE: &[u8] = b"fwoofee -w-";
const BOOP: &[u8] = b"boop >w<";

fn vfs() -> MemDir {
    let file1 = BufferedFile::new(Content::new("text/plain", HEWWO.to_vec()));
    let file2 = BufferedFile::new(Content::new("text/plain", FWOOFEE.to_vec()));
    let file3 = BufferedFile::new(Content::new("text/plain", BOOP.to_vec()));

    let mut innermost = MemDir::new();
    innermost.add(VPath::new("file3.txt"), file3.to_dyn());

    let mut inner = MemDir::new();
    inner.add(VPath::new("file1.txt"), file1.to_dyn());
    inner.add(VPath::new("file2.txt"), file2.to_dyn());
    inner.add(VPath::new("innermost"), innermost.to_dyn());

    let mut vfs = MemDir::new();
    vfs.add(VPath::new("inner"), inner.to_dyn());
    vfs
}

#[test]
fn dir1() {
    let outer = vfs();
    let inner = Cd::new(outer, VPathBuf::new("inner"));

    let mut dir = entries(&inner, VPath::ROOT);
    dir.sort();
    assert_eq!(
        dir,
        vec![
            VPathBuf::new("file1.txt"),
            VPathBuf::new("file2.txt"),
            VPathBuf::new("innermost"),
        ]
    );
}

#[test]
fn dir2() {
    let outer = vfs();
    let innermost = Cd::new(&outer, VPathBuf::new("inner/innermost"));

    let mut dir = entries(&innermost, VPath::ROOT);
    dir.sort();
    assert_eq!(dir, vec![VPathBuf::new("file3.txt")]);
}

#[test]
fn content() {
    let outer = vfs();
    let inner = Cd::new(&outer, VPathBuf::new("inner"));

    assert_eq!(
        query::<Content>(&inner, VPath::new("test1.txt")).map(Content::bytes),
        query::<Content>(&outer, VPath::new("inner/test1.txt")).map(Content::bytes)
    );
}
