use super::*;

/// Main entry point into `just`. Parse arguments from `args` and run.
#[allow(clippy::missing_errors_doc)]
pub fn run(args: impl Iterator<Item = impl Into<OsString> + Clone>) -> Result<(), i32> {
  #[cfg(windows)]
  ansi_term::enable_ansi_support().ok();

  let app = Config::app();

  let matches = app.try_get_matches_from(args).map_err(|err| {
    err.print().ok();
    err.exit_code()
  })?;

  let config = Config::from_matches(&matches).map_err(Error::from);

  let (color, verbosity) = config
    .as_ref()
    .map(|config| (config.color, config.verbosity))
    .unwrap_or_default();

  let loader = Loader::new();

  config
    .and_then(|config| {
      SignalHandler::install(config.verbosity)?;
      config.subcommand.execute(&config, &loader)
    })
    .map_err(|error| {
      if !verbosity.quiet() && error.print_message() {
        eprintln!("{}", error.color_display(color.stderr()));
      }
      error.code().unwrap_or(EXIT_FAILURE)
    })
}

#[cfg(test)]
mod tests {
  use super::*;

  #[test]
  fn run_can_be_called_more_than_once() {
    let tmp = testing::tempdir();
    fs::write(tmp.path().join("justfile"), "foo:").unwrap();
    let search_directory = format!("{}/", tmp.path().to_str().unwrap());
    run(["just", &search_directory].iter()).unwrap();
    run(["just", &search_directory].iter()).unwrap();
  }
}
