use gix_features::{progress, progress::Progress};
use gix_transport::{client, client::SetServiceResponse, Service};
use maybe_async::maybe_async;

use super::{Error, Outcome};
use crate::{credentials, handshake::refs};

/// Perform a handshake with the server on the other side of `transport`, with `authenticate` being used if authentication
/// turns out to be required. `extra_parameters` are the parameters `(name, optional value)` to add to the handshake,
/// each time it is performed in case authentication is required.
/// `progress` is used to inform about what's currently happening.
#[allow(clippy::result_large_err)]
#[maybe_async]
pub async fn handshake<AuthFn, T>(
    mut transport: T,
    service: Service,
    mut authenticate: AuthFn,
    extra_parameters: Vec<(String, Option<String>)>,
    progress: &mut impl Progress,
) -> Result<Outcome, Error>
where
    AuthFn: FnMut(credentials::helper::Action) -> credentials::protocol::Result,
    T: client::Transport,
{
    let _span = gix_features::trace::detail!("gix_protocol::handshake()", service = ?service, extra_parameters = ?extra_parameters);
    let (server_protocol_version, refs, capabilities) = {
        progress.init(None, progress::steps());
        progress.set_name("handshake".into());
        progress.step();

        let extra_parameters: Vec<_> = extra_parameters
            .iter()
            .map(|(k, v)| (k.as_str(), v.as_deref()))
            .collect();
        let supported_versions: Vec<_> = transport.supported_protocol_versions().into();

        let result = transport.handshake(service, &extra_parameters).await;
        let SetServiceResponse {
            actual_protocol,
            capabilities,
            refs,
        } = match result {
            Ok(v) => Ok(v),
            Err(client::Error::Io(ref err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {
                drop(result); // needed to workaround this: https://github.com/rust-lang/rust/issues/76149
                let url = transport.to_url().into_owned();
                progress.set_name("authentication".into());
                let credentials::protocol::Outcome { identity, next } =
                    authenticate(credentials::helper::Action::get_for_url(url.clone()))?
                        .ok_or(Error::EmptyCredentials)?;
                transport.set_identity(identity)?;
                progress.step();
                progress.set_name("handshake (authenticated)".into());
                match transport.handshake(service, &extra_parameters).await {
                    Ok(v) => {
                        authenticate(next.store())?;
                        Ok(v)
                    }
                    // Still no permission? Reject the credentials.
                    Err(client::Error::Io(err)) if err.kind() == std::io::ErrorKind::PermissionDenied => {
                        authenticate(next.erase())?;
                        return Err(Error::InvalidCredentials { url, source: err });
                    }
                    // Otherwise, do nothing, as we don't know if it actually got to try the credentials.
                    // If they were previously stored, they remain. In the worst case, the user has to enter them again
                    // next time they try.
                    Err(err) => Err(err),
                }
            }
            Err(err) => Err(err),
        }?;

        if !supported_versions.is_empty() && !supported_versions.contains(&actual_protocol) {
            return Err(Error::TransportProtocolPolicyViolation {
                actual_version: actual_protocol,
            });
        }

        let parsed_refs = match refs {
            Some(mut refs) => {
                assert!(
                    matches!(
                        actual_protocol,
                        gix_transport::Protocol::V0 | gix_transport::Protocol::V1
                    ),
                    "Only V(0|1) auto-responds with refs"
                );
                Some(
                    refs::from_v1_refs_received_as_part_of_handshake_and_capabilities(&mut refs, capabilities.iter())
                        .await?,
                )
            }
            None => None,
        };
        (actual_protocol, parsed_refs, capabilities)
    }; // this scope is needed, see https://github.com/rust-lang/rust/issues/76149

    Ok(Outcome {
        server_protocol_version,
        refs,
        capabilities,
    })
}
