use super::Iter;
use crate::bstr::BString;
use crate::util::OwnedOrStaticAtomicBool;
use crate::worktree::IndexPersistedOrInMemory;
use crate::{dirwalk, PathspecDetached, Repository};
use std::path::PathBuf;

/// An entry of the directory walk as returned by the [iterator](Iter).
pub struct Item {
    /// The directory entry.
    pub entry: gix_dir::Entry,
    /// `collapsed_directory_status` is `Some(dir_status)` if this entry was part of a directory with the given
    /// `dir_status` that wasn't the same as the one of `entry` and if [gix_dir::walk::Options::emit_collapsed] was
    /// [gix_dir::walk::CollapsedEntriesEmissionMode::OnStatusMismatch]. It will also be `Some(dir_status)` if that option
    /// was [gix_dir::walk::CollapsedEntriesEmissionMode::All].
    pub collapsed_directory_status: Option<gix_dir::entry::Status>,
}

impl Item {
    fn new(entry: gix_dir::EntryRef<'_>, collapsed_directory_status: Option<gix_dir::entry::Status>) -> Self {
        Item {
            entry: entry.to_owned(),
            collapsed_directory_status,
        }
    }
}

/// The outcome of fully consumed [dirwalk iterator](Iter).
pub struct Outcome {
    /// The index originally passed in to create the iterator.
    pub index: IndexPersistedOrInMemory,
    /// The excludes stack used for the dirwalk, for access of `.gitignore` information.
    pub excludes: gix_worktree::Stack,
    /// The pathspecs used to guide the operation,
    pub pathspec: PathspecDetached,
    /// The root actually being used for the traversal, and useful to transform the paths returned for the user.
    /// It's always within the [`work-dir`](Repository::work_dir).
    pub traversal_root: PathBuf,
    /// The actual result of the dirwalk.
    pub dirwalk: gix_dir::walk::Outcome,
}

/// The error returned by [Repository::dirwalk_iter()].
#[derive(Debug, thiserror::Error)]
#[allow(missing_docs)]
pub enum Error {
    #[error("Failed to spawn producer thread")]
    #[cfg(feature = "parallel")]
    SpawnThread(#[from] std::io::Error),
    #[error(transparent)]
    #[cfg(not(feature = "parallel"))]
    Dirwalk(#[from] dirwalk::Error),
    #[error(transparent)]
    #[cfg(not(feature = "parallel"))]
    DetachPathSpec(#[from] std::io::Error),
}

/// Lifecycle
impl Iter {
    pub(crate) fn new(
        repo: &Repository,
        index: IndexPersistedOrInMemory,
        patterns: Vec<BString>,
        should_interrupt: OwnedOrStaticAtomicBool,
        options: dirwalk::Options,
    ) -> Result<Iter, Error> {
        #[cfg(feature = "parallel")]
        {
            let repo = repo.clone().into_sync();
            let (tx, rx) = std::sync::mpsc::channel();
            let handle = std::thread::Builder::new()
                .name("gix::dirwalk::iter::producer".into())
                .spawn({
                    let should_interrupt = should_interrupt.clone();
                    move || -> Result<Outcome, dirwalk::Error> {
                        let repo: Repository = repo.into();
                        let mut collect = Collect { tx };
                        let out = repo.dirwalk(&index, patterns, &should_interrupt, options, &mut collect)?;
                        Ok(Outcome {
                            index,
                            excludes: out.excludes.detach(),
                            pathspec: out.pathspec.detach().map_err(|err| {
                                dirwalk::Error::Walk(gix_dir::walk::Error::ReadDir {
                                    path: repo.git_dir().to_owned(),
                                    source: err,
                                })
                            })?,
                            traversal_root: out.traversal_root,
                            dirwalk: out.dirwalk,
                        })
                    }
                })?;

            Ok(Iter {
                rx_and_join: Some((rx, handle)),
                should_interrupt,
                out: None,
            })
        }
        #[cfg(not(feature = "parallel"))]
        {
            let mut collect = Collect { items: Vec::new() };
            let out = repo.dirwalk(&index, patterns, &should_interrupt, options, &mut collect)?;
            let out = Outcome {
                index,
                excludes: out.excludes.detach(),
                pathspec: out.pathspec.detach()?,
                traversal_root: out.traversal_root,
                dirwalk: out.dirwalk,
            };

            Ok(Iter {
                items: collect.items.into_iter(),
                out: Some(out),
            })
        }
    }
}

/// Access
impl Iter {
    /// Return the outcome of the iteration, or `None` if the iterator isn't fully consumed.
    pub fn outcome_mut(&mut self) -> Option<&mut Outcome> {
        self.out.as_mut()
    }

    /// Turn the iterator into the iteration outcome, which is `None` on error or if the iteration
    /// isn't complete.
    pub fn into_outcome(mut self) -> Option<Outcome> {
        self.out.take()
    }
}

impl Iterator for Iter {
    type Item = Result<Item, dirwalk::Error>;

    fn next(&mut self) -> Option<Self::Item> {
        #[cfg(feature = "parallel")]
        {
            let (rx, _join) = self.rx_and_join.as_ref()?;
            match rx.recv().ok() {
                Some(item) => Some(Ok(item)),
                None => {
                    let (_rx, handle) = self.rx_and_join.take()?;
                    match handle.join().expect("no panic") {
                        Ok(out) => {
                            self.out = Some(out);
                            None
                        }
                        Err(err) => Some(Err(err)),
                    }
                }
            }
        }
        #[cfg(not(feature = "parallel"))]
        self.items.next().map(Ok)
    }
}

#[cfg(feature = "parallel")]
impl Drop for Iter {
    fn drop(&mut self) {
        crate::util::parallel_iter_drop(self.rx_and_join.take(), &self.should_interrupt);
    }
}

struct Collect {
    #[cfg(feature = "parallel")]
    tx: std::sync::mpsc::Sender<Item>,
    #[cfg(not(feature = "parallel"))]
    items: Vec<Item>,
}

impl gix_dir::walk::Delegate for Collect {
    fn emit(
        &mut self,
        entry: gix_dir::EntryRef<'_>,
        collapsed_directory_status: Option<gix_dir::entry::Status>,
    ) -> gix_dir::walk::Action {
        // NOTE: we assume that the receiver triggers interruption so the operation will stop if the receiver is down.
        let item = Item::new(entry, collapsed_directory_status);
        #[cfg(feature = "parallel")]
        self.tx.send(item).ok();
        #[cfg(not(feature = "parallel"))]
        self.items.push(item);
        gix_dir::walk::Action::Continue
    }
}
