//! Rustdoc's FileSystem abstraction module.
//!
//! On Windows this indirects IO into threads to work around performance issues
//! with Defender (and other similar virus scanners that do blocking operations).
//! On other platforms this is a thin shim to fs.
//!
//! Only calls needed to permit this workaround have been abstracted: thus
//! fs::read is still done directly via the fs module; if in future rustdoc
//! needs to read-after-write from a file, then it would be added to this
//! abstraction.

use std::fs;
use std::io;
use std::path::Path;
use std::sync::mpsc::{channel, Receiver, Sender};
use std::sync::Arc;

macro_rules! try_err {
    ($e:expr, $file:expr) => {{
        match $e {
            Ok(e) => e,
            Err(e) => return Err(E::new(e, $file)),
        }
    }};
}

pub trait PathError {
    fn new<P: AsRef<Path>>(e: io::Error, path: P) -> Self;
}

pub struct ErrorStorage {
    sender: Option<Sender<Option<String>>>,
    receiver: Receiver<Option<String>>,
}

impl ErrorStorage {
    pub fn new() -> ErrorStorage {
        let (sender, receiver) = channel();
        ErrorStorage { sender: Some(sender), receiver }
    }

    /// Prints all stored errors. Returns the number of printed errors.
    pub fn write_errors(&mut self, diag: &rustc_errors::Handler) -> usize {
        let mut printed = 0;
        // In order to drop the sender part of the channel.
        self.sender = None;

        for msg in self.receiver.iter() {
            if let Some(ref error) = msg {
                diag.struct_err(&error).emit();
                printed += 1;
            }
        }
        printed
    }
}

pub struct DocFS {
    sync_only: bool,
    errors: Arc<ErrorStorage>,
}

impl DocFS {
    pub fn new(errors: &Arc<ErrorStorage>) -> DocFS {
        DocFS { sync_only: false, errors: Arc::clone(errors) }
    }

    pub fn set_sync_only(&mut self, sync_only: bool) {
        self.sync_only = sync_only;
    }

    pub fn create_dir_all<P: AsRef<Path>>(&self, path: P) -> io::Result<()> {
        // For now, dir creation isn't a huge time consideration, do it
        // synchronously, which avoids needing ordering between write() actions
        // and directory creation.
        fs::create_dir_all(path)
    }

    pub fn write<P, C, E>(&self, path: P, contents: C) -> Result<(), E>
    where
        P: AsRef<Path>,
        C: AsRef<[u8]>,
        E: PathError,
    {
        if !self.sync_only && cfg!(windows) {
            // A possible future enhancement after more detailed profiling would
            // be to create the file sync so errors are reported eagerly.
            let contents = contents.as_ref().to_vec();
            let path = path.as_ref().to_path_buf();
            let sender = self.errors.sender.clone().unwrap();
            rayon::spawn(move || match fs::write(&path, &contents) {
                Ok(_) => {
                    sender
                        .send(None)
                        .expect(&format!("failed to send error on \"{}\"", path.display()));
                }
                Err(e) => {
                    sender
                        .send(Some(format!("\"{}\": {}", path.display(), e)))
                        .expect(&format!("failed to send non-error on \"{}\"", path.display()));
                }
            });
            Ok(())
        } else {
            Ok(try_err!(fs::write(&path, contents), path))
        }
    }
}
