mod common;

use crate::common::asynchronous::InMemoryBlockDevice;
use exfat_slim::asynchronous::{error::ExFatError, file_system::FileSystem};
use log::info;

#[tokio::main(flavor = "current_thread")]
async fn main() -> Result<(), ExFatError<InMemoryBlockDevice>> {
    env_logger::init();
    color_backtrace::install();

    // read the boot sector of the file system
    info!("reading boot sector of file system");
    let io = InMemoryBlockDevice::new();
    let mut fs = FileSystem::new(io);

    let directory = "/bubble/gum";
    let path = format!("{directory}/blue.txt");

    // confirm that the directory does not yet exist
    info!("checking if directory exists");
    let exists = fs.exists(directory).await?;
    info!("{directory} exists: {exists}");

    // confirm that the file does not yet exist
    info!("checking if file exists");
    let exists = fs.exists(&path).await?;
    info!("{path} exists: {exists}");

    // write bytes to a file
    info!("writing bytes to file");
    fs.write(&path, b"hello").await?;
    info!("wrote file to disk");

    // confirm that the directory exists
    info!("checking if directory exists");
    let exists = fs.exists(directory).await?;
    info!("{directory} directory exists: {exists}");

    // confirm that the file exists
    info!("checking if file exists");
    let exists = fs.exists(&path).await?;
    info!("{path} file exists: {exists}");

    // create an empty directory
    info!("creating empty directory: my_dir");
    fs.create_directory(&format!("{directory}/my_dir")).await?;

    // confirm that the file was created in the directory
    info!("list entries in directory {directory}");
    let mut list = fs.read_dir(directory).await?;
    while let Some(item) = list.next_entry(&mut fs).await? {
        info!("{:?}", item);
    }

    // confirm that the file exists
    let exists = fs.exists(&path).await?;
    info!("{path} file exists: {exists}");

    // confirm that the bytes were written to the file
    let contents = fs.read_to_string(&path).await?;
    info!("contents: {contents}");

    Ok(())
}
