use error::*;
#[cfg(windows)]
use helper::has_executable_extension;
use std::env;
use std::ffi::OsStr;
#[cfg(windows)]
use std::ffi::OsString;
use std::iter;
use std::path::{Path, PathBuf};

pub trait Checker {
    fn is_valid(&self, path: &Path) -> bool;
}

trait PathExt {
    fn has_separator(&self) -> bool;

    fn to_absolute<P>(self, cwd: P) -> PathBuf
    where
        P: AsRef<Path>;
}

impl PathExt for PathBuf {
    fn has_separator(&self) -> bool {
        self.components().count() > 1
    }

    fn to_absolute<P>(self, cwd: P) -> PathBuf
    where
        P: AsRef<Path>,
    {
        if self.is_absolute() {
            self
        } else {
            let mut new_path = PathBuf::from(cwd.as_ref());
            new_path.push(self);
            new_path
        }
    }
}

pub struct Finder;

impl Finder {
    pub fn new() -> Finder {
        Finder
    }

    pub fn find<T, U, V>(
        &self,
        binary_name: T,
        paths: Option<U>,
        cwd: V,
        binary_checker: &dyn Checker,
    ) -> Result<PathBuf>
    where
        T: AsRef<OsStr>,
        U: AsRef<OsStr>,
        V: AsRef<Path>,
    {
        let path = PathBuf::from(&binary_name);

        let binary_path_candidates: Box<dyn Iterator<Item = _>> = if path.has_separator() {
            // Search binary in cwd if the path have a path separator.
            let candidates = Self::cwd_search_candidates(path, cwd).into_iter();
            Box::new(candidates)
        } else {
            // Search binary in PATHs(defined in environment variable).
            let p = paths.ok_or(Error::CannotFindBinaryPath)?;
            let paths: Vec<_> = env::split_paths(&p).collect();

            let candidates = Self::path_search_candidates(path, paths).into_iter();

            Box::new(candidates)
        };

        for p in binary_path_candidates {
            // find a valid binary
            if binary_checker.is_valid(&p) {
                return Ok(p);
            }
        }

        // can't find any binary
        Err(Error::CannotFindBinaryPath)
    }

    fn cwd_search_candidates<C>(binary_name: PathBuf, cwd: C) -> impl IntoIterator<Item = PathBuf>
    where
        C: AsRef<Path>,
    {
        let path = binary_name.to_absolute(cwd);

        Self::append_extension(iter::once(path))
    }

    fn path_search_candidates<P>(
        binary_name: PathBuf,
        paths: P,
    ) -> impl IntoIterator<Item = PathBuf>
    where
        P: IntoIterator<Item = PathBuf>,
    {
        let new_paths = paths.into_iter().map(move |p| p.join(binary_name.clone()));

        Self::append_extension(new_paths)
    }

    #[cfg(unix)]
    fn append_extension<P>(paths: P) -> impl IntoIterator<Item = PathBuf>
    where
        P: IntoIterator<Item = PathBuf>,
    {
        paths
    }

    #[cfg(windows)]
    fn append_extension<P>(paths: P) -> impl IntoIterator<Item = PathBuf>
    where
        P: IntoIterator<Item = PathBuf>,
    {
        // Read PATHEXT env variable and split it into vector of String
        let path_exts =
            env::var_os("PATHEXT").unwrap_or(OsString::from(env::consts::EXE_EXTENSION));

        let exe_extension_vec = env::split_paths(&path_exts)
            .filter_map(|e| e.to_str().map(|e| e.to_owned()))
            .collect::<Vec<_>>();

        paths
            .into_iter()
            .flat_map(move |p| -> Box<dyn Iterator<Item = _>> {
                // Check if path already have executable extension
                if has_executable_extension(&p, &exe_extension_vec) {
                    Box::new(iter::once(p))
                } else {
                    // Appended paths with windows executable extensions.
                    // e.g. path `c:/windows/bin` will expend to:
                    // c:/windows/bin.COM
                    // c:/windows/bin.EXE
                    // c:/windows/bin.CMD
                    // ...
                    let ps = exe_extension_vec.clone().into_iter().map(move |e| {
                        // Append the extension.
                        let mut p = p.clone().to_path_buf().into_os_string();
                        p.push(e);

                        PathBuf::from(p)
                    });

                    Box::new(ps)
                }
            })
    }
}
