// 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.

//! TLS certificate selection hook.

use alloc::{vec, vec::Vec};
use core::{
    ffi::{c_int, c_void},
    marker::PhantomData,
    ptr::{NonNull, null},
    task::Context,
};

use super::{
    CryptoBufferIterator,
    DistinguishedName, //
    SignatureAlgorithm,
    get_peer_certificate_type,
    get_peer_raw_public_key,
};

use crate::{
    CertCallback,
    abort_on_panic,
    config::ProtocolVersion,
    connection::methods::waker_data_from_ssl,
    context::TlsContext,
    ffi::sanitize_slice, //
};

/// Result of certificate selection.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum CertificateSelectionResult {
    /// Certificate selection succeeded.
    Success,
    /// Certificate selection is pending (e.g. waiting for async operation).
    /// The handshake will be paused and can be retried later.
    Pending,
    /// Certificate selection failed. The handshake will be aborted.
    Error,
}

/// Server certificate selection.
///
/// Implementations must be `Send + Sync`. If the selector needs mutable state,
/// use interior mutability (e.g. `Mutex`).
pub trait ServerCertificateSelector<Mode>: Send + Sync {
    /// This method should return `CertificateSelectionResult` to indicate the outcome of the selection.
    fn select(
        &self,
        ctx: ServerCertificateSelectionContext<'_, Mode>,
        waker: Option<&'_ mut Context<'_>>,
    ) -> CertificateSelectionResult;
}

/// Client certificate selection.
///
/// Implementations must be `Send + Sync`. If the selector needs mutable state,
/// use interior mutability (e.g. `Mutex`).
pub trait ClientCertificateSelector<M>: Send + Sync {
    /// This method should return `CertificateSelectionResult` to indicate the outcome of the selection.
    fn select(
        &self,
        ctx: ClientCertificateSelectionContext<'_, M>,
        waker: Option<&'_ mut Context<'_>>,
    ) -> CertificateSelectionResult;
}

/// Certificate selection callback.
pub(crate) unsafe extern "C" fn select_cert_cb<M: CertCallback<Mode>, Mode>(
    ssl: *mut bssl_sys::SSL,
    _ctx: *mut c_void,
) -> c_int {
    let is_server = unsafe {
        // Safety: `ssl` is still valid by BoringSSL invariant.
        bssl_sys::SSL_is_server(ssl) == 1
    };
    let Some(ssl) = NonNull::new(ssl) else {
        return 0;
    };
    let Some(methods) = (unsafe {
        // Safety: this callback is installed by this crate so the ex_data index must be valid.
        M::from_ssl(ssl.as_ptr())
    }) else {
        return 0;
    };
    let waker = unsafe {
        // Safety: this callback is installed by this crate so the associated data must have been
        // set up correctly.
        waker_data_from_ssl(ssl)
    };
    let waker = if let Some(waker) = &waker {
        Some(&mut core::task::Context::from_waker(waker))
    } else {
        None
    };
    if is_server {
        let ctx = ServerCertificateSelectionContext::new(ssl);
        let Some(server_cert_cb) = methods.server_cert_cb() else {
            return 1;
        };
        match abort_on_panic(move || server_cert_cb.select(ctx, waker)) {
            CertificateSelectionResult::Success => 1,
            CertificateSelectionResult::Pending => -1,
            CertificateSelectionResult::Error => 0,
        }
    } else {
        let ctx = ClientCertificateSelectionContext::new(ssl);
        let Some(client_cert_cb) = methods.client_cert_cb() else {
            return 1;
        };
        match abort_on_panic(move || client_cert_cb.select(ctx, waker)) {
            CertificateSelectionResult::Success => 1,
            CertificateSelectionResult::Pending => -1,
            CertificateSelectionResult::Error => 0,
        }
    }
}

/// Server certificate selection context.
#[repr(transparent)]
pub struct ServerCertificateSelectionContext<'a, Mode>(
    NonNull<bssl_sys::SSL>,
    PhantomData<&'a fn() -> Mode>,
);

impl<'a, M> ServerCertificateSelectionContext<'a, M> {
    pub(crate) fn new(ssl: NonNull<bssl_sys::SSL>) -> Self {
        Self(ssl, PhantomData)
    }

    /// Switch context.
    pub fn set_context(&mut self, ctx: &TlsContext<M>) {
        unsafe {
            // Safety: `self.0` is still valid by BoringSSL invariant.
            bssl_sys::SSL_set_SSL_CTX(self.0.as_ptr(), ctx.ptr());
        }
    }

    /// Append `credential` to the list of credentials of this connection.
    ///
    /// Earlier calls to this method append a credential that is preferred over those added
    /// in later calls.
    pub fn add_credential(
        &mut self,
        credential: &super::TlsCredential,
    ) -> Result<(), super::super::errors::Error> {
        crate::check_lib_error!(unsafe {
            // Safety: both `self.0` and `credential` are still valid.
            bssl_sys::SSL_add1_credential(self.0.as_ptr(), credential.ptr())
        });
        Ok(())
    }

    /// Get the peer's [`CertificateType`](super::CertificateType).
    pub fn get_peer_certificate_type(&self) -> Option<super::CertificateType> {
        get_peer_certificate_type(self.0.as_ptr())
    }

    /// Get the peer's raw public key as DER-encoded `SubjectPublicKeyInfo`.
    pub fn get_peer_raw_public_key(&self) -> Option<Vec<u8>> {
        get_peer_raw_public_key(self.0.as_ptr())
    }
}

bssl_macros::bssl_enum! {
    /// Requested certificate types defined in [RFC 5246] §7.4.4.
    ///
    /// [RFC 5246]: <https://datatracker.ietf.org/doc/html/rfc5246#section-7.4.4>
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    #[non_exhaustive]
    pub enum RequestedCertificateType: u8 {
        /// RSA signed certificate.
        RsaSign = 1,
        /// DSS signed certificate.
        DssSign = 2,
        /// RSA signed certificate with a static Diffie-Hellman key.
        RsaFixedDh = 3,
        /// DSS signed certificate with a static Diffie-Hellman key.
        DssFixedDh = 4,
        /// Reserved.
        RsaEphemeralDh = 5,
        /// Reserved.
        DssEphemeralDh = 6,
        /// Reserved.
        FortezzaDms = 20,
    }
}

/// Client Certificate Selection.
pub struct ClientCertificateSelectionContext<'a, Mode>(
    NonNull<bssl_sys::SSL>,
    PhantomData<&'a fn() -> Mode>,
);

impl<'a, M> ClientCertificateSelectionContext<'a, M> {
    pub(crate) fn new(ssl: NonNull<bssl_sys::SSL>) -> Self {
        Self(ssl, PhantomData)
    }

    pub(crate) fn ptr(&self) -> *mut bssl_sys::SSL {
        self.0.as_ptr()
    }

    /// Protocol version selected.
    ///
    /// This method returns [`None`] if the protocol version is unrecognised.
    pub fn protocol_version(&self) -> Option<ProtocolVersion> {
        ProtocolVersion::try_from(unsafe {
            // Safety: `self.0` is still valid by BoringSSL invariant.
            bssl_sys::SSL_version(self.ptr())
        })
        .ok()
    }
    /// Get verification algorithm from the peer.
    ///
    /// If a signature algorithm is unrecognised, it will be reported as an `Err` value.
    /// This method might return an empty list if the protocol version is not TLS 1.3.
    pub fn get_tls13_peer_verification_algorithms(&self) -> Vec<Result<SignatureAlgorithm, u16>> {
        let mut algs = null();
        let len = unsafe {
            // Safety: `self.0` is still valid by BoringSSL invariant.
            bssl_sys::SSL_get0_peer_verify_algorithms(self.ptr(), &raw mut algs)
        };
        if let Some(slice) = unsafe {
            // Safety: `algs` is only live within this call.
            sanitize_slice(algs, len)
        } {
            slice
                .iter()
                .copied()
                .map(SignatureAlgorithm::try_from)
                .collect()
        } else {
            vec![]
        }
    }

    /// Get TLS 1.2 certificate types.
    ///
    /// If a certificate type is unrecognised, it will be reported as an `Err` value.
    /// This method returns an empty list if the protocol version is TLS 1.3.
    pub fn get_tls12_certificate_types(&self) -> Vec<Result<RequestedCertificateType, u8>> {
        let mut types = null();
        let len = unsafe {
            // Safety: `self.0` is still valid by BoringSSL invariant.
            bssl_sys::SSL_get0_certificate_types(self.ptr(), &raw mut types)
        };
        if let Some(slice) = unsafe {
            // Safety: `types` is only live within this call.
            sanitize_slice(types, len)
        } {
            slice
                .iter()
                .copied()
                .map(RequestedCertificateType::try_from)
                .collect()
        } else {
            vec![]
        }
    }

    /// Get server requested CAs for client authentication.
    ///
    /// These names are sent by the server and they are the acceptable CAs by server.
    pub fn get_server_ca_list(&self) -> Vec<DistinguishedName> {
        let names = unsafe {
            // Safety: `self.ptr()` is still valid by BoringSSL invariant.
            bssl_sys::SSL_get0_server_requested_CAs(self.ptr())
        };
        let names: CryptoBufferIterator<'_, DistinguishedName> = unsafe {
            // Safety: `names` is owned by SSL and only live within this call.
            CryptoBufferIterator::new(names)
        };
        names.collect()
    }

    /// Append `credential` to the list of credentials of this connection.
    ///
    /// Earlier calls to this method append a credential that is preferred over those added
    /// in later calls.
    pub fn add_credential(
        &mut self,
        credential: &super::TlsCredential,
    ) -> Result<(), super::super::errors::Error> {
        crate::check_lib_error!(unsafe {
            // Safety: both `self.0` and `credential` are still valid.
            bssl_sys::SSL_add1_credential(self.0.as_ptr(), credential.ptr())
        });
        Ok(())
    }

    /// Get the peer's [`CertificateType`](super::CertificateType).
    pub fn get_peer_certificate_type(&self) -> Option<super::CertificateType> {
        super::get_peer_certificate_type(self.ptr())
    }

    /// Get the peer's raw public key as DER-encoded `SubjectPublicKeyInfo`.
    pub fn get_peer_raw_public_key(&self) -> Option<Vec<u8>> {
        super::get_peer_raw_public_key(self.ptr())
    }
}
