use std::borrow::Cow;

/// Entry point for running tests
#[derive(Debug, Default)]
pub struct TestCases {
    runner: std::cell::RefCell<crate::RunnerSpec>,
    bins: std::cell::RefCell<crate::BinRegistry>,
    substitutions: std::cell::RefCell<crate::elide::Substitutions>,
    has_run: std::cell::Cell<bool>,
}

impl TestCases {
    pub fn new() -> Self {
        let s = Self::default();
        s.runner
            .borrow_mut()
            .include(parse_include(std::env::args_os()));
        s
    }

    /// Load tests from `glob`
    pub fn case(&self, glob: impl AsRef<std::path::Path>) -> &Self {
        self.runner.borrow_mut().case(glob.as_ref(), None);
        self
    }

    /// Overwrite expected status for a test
    pub fn pass(&self, glob: impl AsRef<std::path::Path>) -> &Self {
        self.runner
            .borrow_mut()
            .case(glob.as_ref(), Some(crate::schema::CommandStatus::Success));
        self
    }

    /// Overwrite expected status for a test
    pub fn fail(&self, glob: impl AsRef<std::path::Path>) -> &Self {
        self.runner
            .borrow_mut()
            .case(glob.as_ref(), Some(crate::schema::CommandStatus::Failed));
        self
    }

    /// Overwrite expected status for a test
    pub fn interrupted(&self, glob: impl AsRef<std::path::Path>) -> &Self {
        self.runner.borrow_mut().case(
            glob.as_ref(),
            Some(crate::schema::CommandStatus::Interrupted),
        );
        self
    }

    /// Overwrite expected status for a test
    pub fn skip(&self, glob: impl AsRef<std::path::Path>) -> &Self {
        self.runner
            .borrow_mut()
            .case(glob.as_ref(), Some(crate::schema::CommandStatus::Skipped));
        self
    }

    /// Set default bin, by path, for commands
    pub fn default_bin_path(&self, path: impl AsRef<std::path::Path>) -> &Self {
        let bin = Some(crate::schema::Bin::Path(path.as_ref().into()));
        self.runner.borrow_mut().default_bin(bin);
        self
    }

    /// Set default bin, by name, for commands
    pub fn default_bin_name(&self, name: impl AsRef<str>) -> &Self {
        let bin = Some(crate::schema::Bin::Name(name.as_ref().into()));
        self.runner.borrow_mut().default_bin(bin);
        self
    }

    /// Set default timeout for commands
    pub fn timeout(&self, time: std::time::Duration) -> &Self {
        self.runner.borrow_mut().timeout(Some(time));
        self
    }

    /// Set default environment variable
    pub fn env(&self, key: impl Into<String>, value: impl Into<String>) -> &Self {
        self.runner.borrow_mut().env(key, value);
        self
    }

    /// Add a bin to the "PATH" for cases to use
    pub fn register_bin(
        &self,
        name: impl Into<String>,
        path: impl Into<crate::schema::Bin>,
    ) -> &Self {
        self.bins
            .borrow_mut()
            .register_bin(name.into(), path.into());
        self
    }

    /// Add a series of bins to the "PATH" for cases to use
    pub fn register_bins<N: Into<String>, B: Into<crate::schema::Bin>>(
        &self,
        bins: impl IntoIterator<Item = (N, B)>,
    ) -> &Self {
        self.bins
            .borrow_mut()
            .register_bins(bins.into_iter().map(|(n, b)| (n.into(), b.into())));
        self
    }

    /// Add a variable for normalizing output
    ///
    /// Variable names must be
    /// - Surrounded by `[]`
    /// - Consist of uppercase letters
    ///
    /// Variables will be preserved through `TRYCMD=overwrite` / `TRYCMD=dump`.
    ///
    /// **NOTE:** We do basic search/replaces so new any new output will blindly be replaced.
    ///
    /// Reserved names:
    /// - `[..]`
    /// - `[EXE]`
    /// - `[CWD]`
    /// - `[ROOT]`
    ///
    /// ## Example
    ///
    /// ```rust,no_run
    /// #[test]
    /// fn cli_tests() {
    ///     trycmd::TestCases::new()
    ///         .case("tests/cmd/*.trycmd")
    ///         .insert_var("[VAR]", "value");
    /// }
    /// ```
    pub fn insert_var(
        &self,
        var: &'static str,
        value: impl Into<Cow<'static, str>>,
    ) -> Result<&Self, crate::Error> {
        self.substitutions.borrow_mut().insert(var, value)?;
        Ok(self)
    }

    /// Batch add variables for normalizing output
    ///
    /// See `insert_var`.
    pub fn extend_vars(
        &self,
        vars: impl IntoIterator<Item = (&'static str, impl Into<Cow<'static, str>>)>,
    ) -> Result<&Self, crate::Error> {
        self.substitutions.borrow_mut().extend(vars)?;
        Ok(self)
    }

    /// Run tests
    ///
    /// This will happen on `drop` if not done explicitly
    pub fn run(&self) {
        self.has_run.set(true);

        let mode = parse_mode(std::env::var_os("TRYCMD").as_deref());
        mode.initialize().unwrap();

        let runner = self.runner.borrow_mut().prepare();
        runner.run(&mode, &self.bins.borrow(), &self.substitutions.borrow());
    }
}

impl std::panic::RefUnwindSafe for TestCases {}

#[doc(hidden)]
impl Drop for TestCases {
    fn drop(&mut self) {
        if !self.has_run.get() && !std::thread::panicking() {
            self.run();
        }
    }
}

// Filter which test cases are run by trybuild.
//
//     $ cargo test -- ui trybuild=tuple_structs.rs
//
// The first argument after `--` must be the trybuild test name i.e. the name of
// the function that has the #[test] attribute and calls trybuild. That's to get
// Cargo to run the test at all. The next argument starting with `trybuild=`
// provides a filename filter. Only test cases whose filename contains the
// filter string will be run.
#[allow(clippy::needless_collect)] // false positive https://github.com/rust-lang/rust-clippy/issues/5991
fn parse_include(args: impl IntoIterator<Item = std::ffi::OsString>) -> Option<Vec<String>> {
    let filters = args
        .into_iter()
        .flat_map(std::ffi::OsString::into_string)
        .filter_map(|arg| {
            const PREFIX: &str = "trycmd=";
            if let Some(remainder) = arg.strip_prefix(PREFIX) {
                if remainder.is_empty() {
                    None
                } else {
                    Some(remainder.to_owned())
                }
            } else {
                None
            }
        })
        .collect::<Vec<String>>();

    if filters.is_empty() {
        None
    } else {
        Some(filters)
    }
}

fn parse_mode(var: Option<&std::ffi::OsStr>) -> crate::Mode {
    if var == Some(std::ffi::OsStr::new("overwrite")) {
        crate::Mode::Overwrite
    } else if var == Some(std::ffi::OsStr::new("dump")) {
        crate::Mode::Dump("dump".into())
    } else {
        crate::Mode::Fail
    }
}
