use crate::builder::{ConfigBuilder, WantsVerifier};
use crate::client::handy;
use crate::client::{ClientConfig, ResolvesClientCert};
use crate::crypto::CryptoProvider;
use crate::error::Error;
use crate::key_log::NoKeyLog;
use crate::msgs::handshake::CertificateChain;
use crate::webpki::{self, WebPkiServerVerifier};
use crate::{verify, versions};
use super::client_conn::Resumption;
use pki_types::{CertificateDer, PrivateKeyDer};
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::marker::PhantomData;
impl ConfigBuilder<ClientConfig, WantsVerifier> {
    pub fn with_root_certificates(
        self,
        root_store: impl Into<Arc<webpki::RootCertStore>>,
    ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
        let algorithms = self
            .state
            .provider
            .signature_verification_algorithms;
        self.with_webpki_verifier(
            WebPkiServerVerifier::new_without_revocation(root_store, algorithms).into(),
        )
    }
    pub fn with_webpki_verifier(
        self,
        verifier: Arc<WebPkiServerVerifier>,
    ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
        ConfigBuilder {
            state: WantsClientCert {
                provider: self.state.provider,
                versions: self.state.versions,
                verifier,
            },
            side: PhantomData,
        }
    }
    pub fn dangerous(self) -> danger::DangerousClientConfigBuilder {
        danger::DangerousClientConfigBuilder { cfg: self }
    }
}
pub(super) mod danger {
    use alloc::sync::Arc;
    use core::marker::PhantomData;
    use crate::client::WantsClientCert;
    use crate::{verify, ClientConfig, ConfigBuilder, WantsVerifier};
    #[derive(Debug)]
    pub struct DangerousClientConfigBuilder {
        pub cfg: ConfigBuilder<ClientConfig, WantsVerifier>,
    }
    impl DangerousClientConfigBuilder {
        pub fn with_custom_certificate_verifier(
            self,
            verifier: Arc<dyn verify::ServerCertVerifier>,
        ) -> ConfigBuilder<ClientConfig, WantsClientCert> {
            ConfigBuilder {
                state: WantsClientCert {
                    provider: self.cfg.state.provider,
                    versions: self.cfg.state.versions,
                    verifier,
                },
                side: PhantomData,
            }
        }
    }
}
#[derive(Clone)]
pub struct WantsClientCert {
    provider: Arc<CryptoProvider>,
    versions: versions::EnabledVersions,
    verifier: Arc<dyn verify::ServerCertVerifier>,
}
impl ConfigBuilder<ClientConfig, WantsClientCert> {
    pub fn with_client_auth_cert(
        self,
        cert_chain: Vec<CertificateDer<'static>>,
        key_der: PrivateKeyDer<'static>,
    ) -> Result<ClientConfig, Error> {
        let private_key = self
            .state
            .provider
            .key_provider
            .load_private_key(key_der)?;
        let resolver =
            handy::AlwaysResolvesClientCert::new(private_key, CertificateChain(cert_chain))?;
        Ok(self.with_client_cert_resolver(Arc::new(resolver)))
    }
    pub fn with_no_client_auth(self) -> ClientConfig {
        self.with_client_cert_resolver(Arc::new(handy::FailResolveClientCert {}))
    }
    pub fn with_client_cert_resolver(
        self,
        client_auth_cert_resolver: Arc<dyn ResolvesClientCert>,
    ) -> ClientConfig {
        ClientConfig {
            provider: self.state.provider,
            alpn_protocols: Vec::new(),
            resumption: Resumption::default(),
            max_fragment_size: None,
            client_auth_cert_resolver,
            versions: self.state.versions,
            enable_sni: true,
            verifier: self.state.verifier,
            key_log: Arc::new(NoKeyLog {}),
            enable_secret_extraction: false,
            enable_early_data: false,
        }
    }
}