use crate::{helper, helper::Cascade, protocol, protocol::Context, Program};

impl Default for Cascade {
    fn default() -> Self {
        Cascade {
            programs: Vec::new(),
            stderr: true,
            use_http_path: false,
            query_user_only: false,
        }
    }
}

/// Initialization
impl Cascade {
    /// Return the programs to run for the current platform.
    ///
    /// These are typically used as basis for all credential cascade invocations, with configured programs following afterwards.
    ///
    /// # Note
    ///
    /// These defaults emulate what typical git installations may use these days, as in fact it's a configurable which comes
    /// from installation-specific configuration files which we cannot know (or guess at best).
    /// This seems like an acceptable trade-off as helpers are ignored if they fail or are not existing.
    pub fn platform_builtin() -> Vec<Program> {
        if cfg!(target_os = "macos") {
            Some("osxkeychain")
        } else if cfg!(target_os = "linux") {
            Some("libsecret")
        } else if cfg!(target_os = "windows") {
            Some("manager-core")
        } else {
            None
        }
        .map(|name| vec![Program::from_custom_definition(name)])
        .unwrap_or_default()
    }
}

/// Builder
impl Cascade {
    /// Extend the list of programs to run `programs`.
    pub fn extend(mut self, programs: impl IntoIterator<Item = Program>) -> Self {
        self.programs.extend(programs);
        self
    }
    /// If `toggle` is true, http(s) urls will use the path portions of the url to obtain a credential for.
    ///
    /// Otherwise, they will only take the user name into account.
    pub fn use_http_path(mut self, toggle: bool) -> Self {
        self.use_http_path = toggle;
        self
    }

    /// If `toggle` is true, a bogus password will be provided to prevent any helper program from prompting for it, nor will
    /// we prompt for the password. The resulting identity will have a bogus password and it's expected to not be used by the
    /// consuming transport.
    pub fn query_user_only(mut self, toggle: bool) -> Self {
        self.query_user_only = toggle;
        self
    }
}

/// Finalize
impl Cascade {
    /// Invoke the cascade by `invoking` each program with `action`, and configuring potential prompts with `prompt` options.
    /// The latter can also be used to disable the prompt entirely when setting the `mode` to [`Disable`][gix_prompt::Mode::Disable];=.
    ///
    /// When _getting_ credentials, all programs are asked until the credentials are complete, stopping the cascade.
    /// When _storing_ or _erasing_ all programs are instructed in order.
    #[allow(clippy::result_large_err)]
    pub fn invoke(&mut self, mut action: helper::Action, mut prompt: gix_prompt::Options<'_>) -> protocol::Result {
        let mut url = action
            .context_mut()
            .map(|ctx| {
                ctx.destructure_url_in_place(self.use_http_path).map(|ctx| {
                    if self.query_user_only && ctx.password.is_none() {
                        ctx.password = Some("".into());
                    }
                    ctx
                })
            })
            .transpose()?
            .and_then(|ctx| ctx.url.take());

        for program in &mut self.programs {
            program.stderr = self.stderr;
            match helper::invoke::raw(program, &action) {
                Ok(None) => {}
                Ok(Some(stdout)) => {
                    let ctx = Context::from_bytes(&stdout)?;
                    if let Some(dst_ctx) = action.context_mut() {
                        if let Some(src) = ctx.path {
                            dst_ctx.path = Some(src);
                        }
                        for (src, dst) in [
                            (ctx.protocol, &mut dst_ctx.protocol),
                            (ctx.host, &mut dst_ctx.host),
                            (ctx.username, &mut dst_ctx.username),
                            (ctx.password, &mut dst_ctx.password),
                        ] {
                            if let Some(src) = src {
                                *dst = Some(src);
                            }
                        }
                        if let Some(src) = ctx.url {
                            dst_ctx.url = Some(src);
                            url = dst_ctx.destructure_url_in_place(self.use_http_path)?.url.take();
                        }
                        if dst_ctx.username.is_some() && dst_ctx.password.is_some() {
                            break;
                        }
                        if ctx.quit.unwrap_or_default() {
                            dst_ctx.quit = ctx.quit;
                            break;
                        }
                    }
                }
                Err(helper::Error::CredentialsHelperFailed { .. }) => continue, // ignore helpers that we can't call
                Err(err) if action.context().is_some() => return Err(err.into()), // communication errors are fatal when getting credentials
                Err(_) => {} // for other actions, ignore everything, try the operation
            }
        }

        if prompt.mode != gix_prompt::Mode::Disable {
            if let Some(ctx) = action.context_mut() {
                ctx.url = url;
                if ctx.username.is_none() {
                    let message = ctx.to_prompt("Username");
                    prompt.mode = gix_prompt::Mode::Visible;
                    ctx.username = gix_prompt::ask(&message, &prompt)
                        .map_err(|err| protocol::Error::Prompt {
                            prompt: message,
                            source: err,
                        })?
                        .into();
                }
                if ctx.password.is_none() {
                    let message = ctx.to_prompt("Password");
                    prompt.mode = gix_prompt::Mode::Hidden;
                    ctx.password = gix_prompt::ask(&message, &prompt)
                        .map_err(|err| protocol::Error::Prompt {
                            prompt: message,
                            source: err,
                        })?
                        .into();
                }
            }
        }

        protocol::helper_outcome_to_result(
            action.context().map(|ctx| helper::Outcome {
                username: ctx.username.clone(),
                password: ctx.password.clone(),
                quit: ctx.quit.unwrap_or(false),
                next: ctx.to_owned().into(),
            }),
            action,
        )
    }
}
