//! No-op backend.

use std::{ffi::OsStr, fmt, path::PathBuf};

use log::*;

use crate::backend::{CopyDest, CopyDestFolder, CopySource};

/// No-op copy destination.
pub struct Null {}
struct NullFolder {
    path: PathBuf,
}

impl Null {
    pub fn create() -> Self {
        Null {}
    }
}

impl fmt::Display for Null {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "NULL")
    }
}

impl CopyDest for Null {
    fn open<'a>(&'a self) -> Result<Box<dyn super::CopyDestFolder<'a>>, crate::CopyError> {
        Ok(Box::new(NullFolder {
            path: PathBuf::new(),
        }))
    }
}

impl<'a> CopyDestFolder<'a> for NullFolder {
    fn add_file(&mut self, name: &OsStr, _src: &dyn CopySource) -> Result<bool, crate::CopyError> {
        let path = self.path.join(name);
        debug!("file {}", path.display());
        Ok(false)
    }

    fn add_directory(
        &mut self,
        name: &OsStr,
    ) -> Result<Box<dyn CopyDestFolder<'a>>, crate::CopyError> {
        let path = self.path.join(name);
        debug!("begin directory {}", path.display());
        Ok(Box::new(NullFolder { path }))
    }

    fn finish(&mut self) -> Result<usize, crate::CopyError> {
        debug!("end directory {}", self.path.display());
        Ok(0)
    }
}
