// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
use {
    crate::{
        directory::FatDirectory,
        node::{Closer, FatNode, Node},
        FatFs,
    },
    anyhow::Error,
    fidl_fuchsia_io as fio,
    fuchsia_zircon::Status,
    futures::{future::BoxFuture, prelude::*},
    scopeguard::defer,
    std::{any::Any, io::Cursor, sync::Arc},
    vfs::{
        directory::{
            dirents_sink::{AppendResult, Sealed, Sink},
            entry::EntryInfo,
            entry_container::Directory,
            traversal_position::TraversalPosition,
        },
        file::File,
    },
};

fn fuzz_node(fs: &FatFs, node: FatNode, depth: u32) -> BoxFuture<'_, Result<(), Status>> {
    async move {
        if depth > 5 {
            // It's possible for a FAT filesystem to contain cycles while technically being legal.
            return Ok(());
        }
        match node {
            FatNode::File(file) => {
                let mut buffer = vec![0u8; 2084];
                let _ = file.read_at(0, &mut buffer).await;
                let _ = file.write_at(256, "qwerty".as_bytes()).await;
                let _ = file.get_size().await;
            }
            FatNode::Dir(dir) => {
                let sink = FuzzSink::new(dir.clone(), depth);
                let (pos, sealed): (TraversalPosition, Box<dyn Sealed>) =
                    dir.read_dirents(&TraversalPosition::Start, Box::new(sink)).await?;
                assert_eq!(pos, TraversalPosition::End);
                let sink = sealed.open().downcast::<FuzzSink>().unwrap();
                sink.walk(fs).await;
            }
        };

        Ok(())
    }
    .boxed()
}

struct FuzzSink {
    entries: Vec<String>,
    dir: Arc<FatDirectory>,
    depth: u32,
}

impl FuzzSink {
    fn new(dir: Arc<FatDirectory>, depth: u32) -> Self {
        Self { entries: Vec::new(), dir, depth }
    }

    async fn walk(&self, fs: &FatFs) {
        for name in self.entries.iter() {
            let mut closer = Closer::new(fs.filesystem());
            let entry = match self.dir.open_child(
                name,
                fio::OpenFlags::RIGHT_READABLE | fio::OpenFlags::RIGHT_WRITABLE,
                0,
                &mut closer,
            ) {
                Ok(entry) => entry,
                Err(_) => continue,
            };

            let _ = fuzz_node(fs, entry, self.depth + 1).await;
        }
    }
}

impl Sink for FuzzSink {
    fn append(mut self: Box<Self>, _entry: &EntryInfo, name: &str) -> AppendResult {
        if name != ".." && name != "." {
            self.entries.push(name.to_owned());
        }
        AppendResult::Ok(self)
    }

    fn seal(self: Box<Self>) -> Box<dyn Sealed> {
        self
    }
}

impl Sealed for FuzzSink {
    fn open(self: Box<Self>) -> Box<dyn Any> {
        self
    }
}

async fn do_fuzz(disk: Cursor<Vec<u8>>) -> Result<(), Error> {
    let fs = FatFs::new(Box::new(disk))?;
    let root: Arc<FatDirectory> = fs.get_fatfs_root();

    root.open_ref(&fs.filesystem().lock().unwrap()).unwrap();
    let _ = fuzz_node(&fs, FatNode::Dir(root.clone()), 0).await;
    defer! { root.close().unwrap() };

    Ok(())
}

pub fn fuzz_fatfs(fs: &[u8]) {
    let mut executor = fuchsia_async::TestExecutor::new().unwrap();
    executor.run_singlethreaded(async {
        let mut vec = fs.to_vec();
        // Make sure the "disk" is always a length that's a multiple of 512.
        let rounded = ((vec.len() / 512) + 1) * 512;
        vec.resize(rounded, 0);
        let cursor = std::io::Cursor::new(vec);

        let _ = do_fuzz(cursor).await;
    });
}
