// Copyright 2026 The BoringSSL Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

use core::ptr::null_mut;

use bssl_x509::{
    params::CertificateVerificationParams,
    store::X509Store, //
};

use super::TlsContextBuilder;
use crate::{
    check_lib_error,
    config::ConfigurationError,
    context::{
        CertificateCache,
        SupportedMode, //
    },
    credentials::{
        CertificateType,
        CertificateVerificationMode,
        SignatureAlgorithm,
        TlsCredential,
        VerifyCertificate,
        cert_cb,
        early_callback::{
            EarlyCallback,
            early_select_cert_cb, //
        }, //
    },
    errors::Error,
    ffi::slice_into_ffi_raw_parts,
    has_duplicates, //
};

/// # Credentials
impl<M> TlsContextBuilder<M>
where
    M: SupportedMode,
{
    /// Set the certificate cache.
    ///
    /// This [`CertificateCache`] can be shared across multiple contexts and their associated
    /// connections.
    /// The cache is recommended for use to reduce memory footprint arising from the X.509-based
    /// authentication.
    pub fn with_certificate_cache(&mut self, cache: Option<&CertificateCache>) -> &mut Self {
        let ctx = self.ptr();
        if let Some(cache) = cache {
            unsafe {
                // Safety: `CertificateCache` is `Send + Sync`
                bssl_sys::SSL_CTX_set1_buffer_pool(ctx, cache.ptr());
            }
        } else {
            unsafe {
                // Safety: we just detach the buffer pool before any active pointer into it is created.
                bssl_sys::SSL_CTX_set1_buffer_pool(ctx, null_mut());
            }
        }
        self
    }

    /// Set certificate verification mode.
    ///
    /// # Client certificate verification for servers, mutual TLS
    ///
    /// Server can choose to request a certificate from the client by setting `mode` to
    /// - [`CertificateVerificationMode::PeerCertRequested`] which may still let handshake complete
    ///   if the certificate request by the server is not fulfilled.
    /// - [`CertificateVerificationMode::PeerCertMandatory`] which will abort handshake if
    ///   the request is not fulfilled.
    pub fn with_certificate_verification_mode(
        &mut self,
        mode: CertificateVerificationMode,
    ) -> &mut Self {
        let conn = self.ptr();
        unsafe {
            // Safety: we only install our own vtable.
            bssl_sys::SSL_CTX_set_verify(conn, mode as _, None);
        }
        self
    }

    /// Set certificate verification mode and custom verifier.
    ///
    /// # Setting custom certificate verifier
    ///
    /// See [`VerifyCertificate`] for how to implement a custom verifier.
    ///
    /// # Client certificate verification for servers, mutual TLS
    ///
    /// Server can choose to request a certificate from the client by setting `mode` to
    /// - [`CertificateVerificationMode::PeerCertRequested`] which may still let handshake complete
    ///   if the certificate request by the server is not fulfilled.
    /// - [`CertificateVerificationMode::PeerCertMandatory`] which will abort handshake if
    ///   the request is not fulfilled.
    pub fn with_certificate_verifier<V>(
        &mut self,
        mode: CertificateVerificationMode,
        verifier: V,
    ) -> &mut Self
    where
        V: VerifyCertificate + 'static,
    {
        let conn = self.ptr();
        unsafe {
            // Safety: we only install our own vtable.
            bssl_sys::SSL_CTX_set_custom_verify(
                conn,
                mode as _,
                Some(cert_cb::<super::methods::RustContextMethods<M>>),
            );
        }
        self.get_context_methods().verify_certificate_methods = Some(Box::new(verifier) as _);
        self
    }

    /// Remove custom certificate verifier.
    pub fn without_certificate_verifier(&mut self, mode: CertificateVerificationMode) -> &mut Self {
        let conn = self.ptr();
        unsafe {
            // Safety: we only uninstall the vtable.
            bssl_sys::SSL_CTX_set_custom_verify(conn, mode as _, None);
        }
        self.get_context_methods().verify_certificate_methods = None;
        self
    }

    /// Set custom certificate selection callback.
    ///
    /// See [`EarlyCallback`] for its semantics.
    pub fn with_early_callback<S>(&mut self, handler: S) -> &mut Self
    where
        S: EarlyCallback<M> + 'static,
    {
        let ctx = self.ptr();
        let methods = self.get_context_methods();
        unsafe {
            // Safety: we only install our own vtable.
            bssl_sys::SSL_CTX_set_select_certificate_cb(
                ctx,
                Some(early_select_cert_cb::<M, super::methods::RustContextMethods<M>>),
            );
        }
        methods.early_callback_handler = Some(Box::new(handler) as _);
        self
    }

    /// Remove custom certificate selection callback.
    pub fn without_early_callback(&mut self) -> &mut Self {
        let ctx = self.ptr();
        let methods = self.get_context_methods();
        unsafe {
            // Safety: we only uninstall the vtable.
            bssl_sys::SSL_CTX_set_select_certificate_cb(ctx, None);
        }
        methods.early_callback_handler = None;
        self
    }

    /// Append `credential` to the list of credentials of this context.
    pub fn with_credential(&mut self, credential: TlsCredential) -> Result<&mut Self, Error> {
        check_lib_error!(unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - the method will bump the refcount of the credential for ownership.
            bssl_sys::SSL_CTX_add1_credential(self.ptr(), credential.ptr())
        });
        Ok(self)
    }

    /// Set the list of accepted peer certificate types.
    pub fn with_accepted_peer_cert_types(
        &mut self,
        types: &[CertificateType],
    ) -> Result<&mut Self, Error> {
        let (ptr, len) = slice_into_ffi_raw_parts(types);
        check_lib_error!(unsafe {
            // Safety:
            // - `self.ptr()` is a valid `SSL_CTX` handle.
            // - `ptr` is a valid pointer to an array of `i32` representing certificate types.
            // - `len` is the number of elements in the array.
            // - The function copies the data, so the pointer only needs to be valid for the call.
            bssl_sys::SSL_CTX_set1_accepted_peer_cert_types(self.ptr(), ptr as *const _, len)
        });
        Ok(self)
    }

    /// Set the list of available client certificate types.
    pub fn with_available_client_cert_types(
        &mut self,
        types: &[CertificateType],
    ) -> Result<&mut Self, Error> {
        let (ptr, len) = slice_into_ffi_raw_parts(types);
        check_lib_error!(unsafe {
            // Safety:
            // - `self.ptr()` is a valid `SSL_CTX` handle.
            // - `ptr` is a valid pointer to an array of `i32` representing certificate types.
            // - `len` is the number of elements in the array.
            // - The function copies the data, so the pointer only needs to be valid for the call.
            bssl_sys::SSL_CTX_set1_available_client_cert_types(self.ptr(), ptr as *const _, len)
        });
        Ok(self)
    }
}

/// # Certificate verification
impl<M> TlsContextBuilder<M> {
    /// Set certificate verification parameters.
    pub fn with_certificate_verification_params(
        &mut self,
        params: &CertificateVerificationParams,
    ) -> Result<&mut Self, Error> {
        check_lib_error!(unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - `SSL_CTX_set1_param` bumps the ref-count on the `params`.
            bssl_sys::SSL_CTX_set1_param(self.ptr(), params.as_ptr())
        });
        Ok(self)
    }

    /// Enable signed certificate timestamps.
    ///
    /// This method will instruct the client connections to request Signed Certificate Timestamps.
    /// See [RFC 6962] for more information.
    ///
    /// [RFC 6962]: https://datatracker.ietf.org/doc/html/rfc6962
    pub fn enable_signed_certificate_timestamps(&mut self) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_enable_signed_cert_timestamps(self.ptr());
        }
        self
    }

    /// Set certificate verification store.
    pub fn with_certificate_store(&mut self, store: &X509Store) -> &mut Self {
        unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - `SSL_CTX_set1_verify_cert_store` bumps the ref-count on `store`.
            assert_eq!(
                bssl_sys::SSL_CTX_set1_verify_cert_store(self.ptr(), store.as_mut_ptr()),
                1,
            );
        }
        self
    }

    /// Set a preference list of signature algorithms for verification.
    ///
    /// This method returns [`ConfigurationError::InvalidParameters`] if the list of algorithms
    /// contains duplicate entries.
    pub fn with_signature_verification_algorithm_preferences(
        &mut self,
        algs: &[SignatureAlgorithm],
    ) -> Result<&mut Self, Error> {
        let algs: &[u16] = unsafe {
            // Safety: `SignatureAlgorithm` has a `repr(u16)` and maps to preferences correctly
            // by construction.
            core::mem::transmute(algs)
        };
        if has_duplicates(algs) {
            return Err(Error::Configuration(ConfigurationError::InvalidParameters));
        }

        let (prefs, prefs_len) = slice_into_ffi_raw_parts(algs);
        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_set_verify_algorithm_prefs(self.ptr(), prefs, prefs_len)
        });
        Ok(self)
    }

    /// Set a preference list of algorithms for signing.
    ///
    /// This method returns [`ConfigurationError::InvalidParameters`] if the list of algorithms
    /// contains duplicate entries.
    pub fn with_signing_algorithm_preferences(
        &mut self,
        algs: &[SignatureAlgorithm],
    ) -> Result<&mut Self, Error> {
        let algs: &[u16] = unsafe {
            // Safety: `SignatureAlgorithm` has a `repr(u16)` and maps to preferences correctly
            // by construction.
            core::mem::transmute(algs)
        };
        if has_duplicates(algs) {
            return Err(Error::Configuration(ConfigurationError::InvalidParameters));
        }

        let (prefs, prefs_len) = slice_into_ffi_raw_parts(algs);
        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_set_signing_algorithm_prefs(self.ptr(), prefs, prefs_len)
        });
        Ok(self)
    }
}
