// 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 context builder and context type

use alloc::{
    boxed::Box,
    sync::Arc, //
};
use core::{
    marker::PhantomData,
    mem::forget,
    ptr::NonNull, //
};

use bssl_crypto::FfiSlice;

use crate::{
    check_lib_error,
    config::{
        CompliancePolicy,
        ConfigurationError,
        KeyExchangeGroupFlag,
        KeyExchangeGroups,
        ProtocolVersion, //
    },
    connection::{
        Client,
        Server,
        TlsConnectionBuilder,
        methods::HasTlsConnectionMethod, //
    },
    context::methods::HasTlsContextMethod,
    errors::Error,
    has_duplicates, //
};

mod credentials;
mod methods;
mod sessions;

/// TLS or DTLS mode
pub enum TlsMode {}

/// DTLS mode
pub enum DtlsMode {}

/// QUIC mode
pub enum QuicMode {}

pub(crate) trait HasBasicIo {}

/// A collection of supported mode of operations.
pub trait SupportedMode: HasTlsContextMethod + HasTlsConnectionMethod {}

impl SupportedMode for TlsMode {}
impl SupportedMode for DtlsMode {}
impl SupportedMode for QuicMode {}

impl HasBasicIo for TlsMode {}
impl HasBasicIo for DtlsMode {}

/// General TLS configuration
///
/// The `Mode` generic can be either [`TlsMode`] or [`QuicMode`].
/// This generic governs the kind of [`TlsConnection`] that can be constructed.
pub struct TlsContextBuilder<Mode = TlsMode> {
    ptr: NonNull<bssl_sys::SSL_CTX>,
    cert_cache: Option<Arc<CertificateCache>>,
    _p: PhantomData<fn() -> Mode>,
}

impl<M> TlsContextBuilder<M> {
    fn ptr(&self) -> *mut bssl_sys::SSL_CTX {
        self.ptr.as_ptr()
    }
}

impl<M> TlsContextBuilder<M>
where
    M: HasTlsContextMethod,
{
    fn new_inner(method: *const bssl_sys::SSL_METHOD) -> Self {
        let Some(ptr) = NonNull::new(unsafe {
            // Safety: this call only makes allocations
            bssl_sys::SSL_CTX_new(method)
        }) else {
            panic!("allocation failure")
        };
        let this = TlsContextBuilder {
            ptr,
            cert_cache: None,
            _p: PhantomData,
        };
        let rc = unsafe {
            // Safety: `ctx` is still valid
            bssl_sys::SSL_CTX_set_ex_data(
                ptr.as_ptr(),
                M::registration(),
                Box::into_raw(Box::new(methods::RustContextMethods::<M>::new())) as _,
            )
        };
        assert!(rc == 1);
        this
    }
}

/// # Make a TLS context builder
impl TlsContextBuilder<TlsMode> {
    /// Creates a new TLS context builder.
    pub fn new_tls() -> Self {
        Self::new_inner(unsafe {
            // Safety: this call returns a static immutable data
            bssl_sys::TLS_method()
        })
    }
}

/// # Make a DTLS context builder operating in pure DTLS mode
impl TlsContextBuilder<DtlsMode> {
    /// Creates a new DTLS context builder.
    pub fn new_dtls() -> Self {
        Self::new_inner(unsafe {
            // Safety: this call returns a static immutable data
            bssl_sys::DTLS_method()
        })
    }
}

/// # Configure the context through a context builder
impl<M> TlsContextBuilder<M>
where
    M: HasTlsContextMethod,
{
    /// Builds and returns the configured TLS context.
    pub fn build(mut self) -> TlsContext<M> {
        let TlsContextBuilder {
            ptr,
            ref mut cert_cache,
            ..
        } = self;
        let cert_cache = cert_cache.take();
        // We must disarm the drop activated by the builder and pass on the ownership.
        // Now `self` has no destructors to call.
        forget(self);
        TlsContext {
            ptr,
            cert_cache,
            _p: PhantomData,
        }
    }

    #[allow(unused)]
    fn get_context_methods(&mut self) -> &mut methods::RustContextMethods<M> {
        let methods = unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_get_ex_data(self.ptr(), M::registration())
        };
        if methods.is_null() {
            panic!("context method goes missing")
        }
        unsafe {
            // Safety: `methods` must be constructed by `new_inner`
            &mut *(methods as *mut methods::RustContextMethods<M>)
        }
    }

    /// Set the minimum acceptable protocol.
    ///
    /// If `version` is set to `None`, the library will choose a default minimum version.
    /// - For TLS, it is TLS 1.3
    /// - For DTLS, it is DTLS 1.2
    ///
    /// This configuration fails if the protocol version is incompatible with the selected TLS
    /// flavour, such as setting TLS 1.3 for DTLS flavour.
    pub fn with_min_protocol(
        &mut self,
        version: Option<ProtocolVersion>,
    ) -> Result<&mut Self, Error> {
        let version = version.map_or(0, |ver| ver as u16);
        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`
            bssl_sys::SSL_CTX_set_min_proto_version(self.ptr(), version)
        });
        Ok(self)
    }

    /// Set the maximum acceptable protocol.
    ///
    /// If `version` is set to `None`, the library will choose a default maximum version.
    /// - For TLS, it is TLS 1.3
    /// - For DTLS, it is DTLS 1.2
    ///
    /// This configuration fails if the protocol version is incompatible with the selected TLS
    /// flavour, such as setting TLS 1.3 for DTLS flavour.
    pub fn with_max_protocol(
        &mut self,
        version: Option<ProtocolVersion>,
    ) -> Result<&mut Self, Error> {
        let version = version.map_or(0, |ver| ver as u16);
        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`
            bssl_sys::SSL_CTX_set_max_proto_version(self.ptr(), version)
        });
        Ok(self)
    }

    /// Set acceptable key exchange groups.
    ///
    /// This method sets up the acceptable key exchange groups and the list of groups advertised by
    /// the client.
    ///
    /// If the supplied list is empty, the context will revert back to a default list of groups.
    ///
    /// If the `flags` list is not empty, its length must match that of `groups`.
    ///
    /// This method returns [`ConfigurationError::InvalidParameters`] if the key exchange groups are not unique in the list.
    pub fn with_key_exchange_groups(
        &mut self,
        groups: &[KeyExchangeGroups],
        flags: &[KeyExchangeGroupFlag],
    ) -> Result<&mut Self, Error> {
        // TODO(@xfding): maybe we should use zerocopy here when v0.9 is finalised
        let groups: &[u16] = unsafe {
            // Safety: `KeyExchangeGroups` has the same layout as a `u16`,
            // so `&[KeyExchangeGroups]` and `&[u16]` has the same layout.
            core::mem::transmute(groups)
        };
        let flags: &[u32] = unsafe {
            // Safety: `KeyExchangeGroupFlag` has the same layout as a `u32` through
            // `repr(transparent)`.
            core::mem::transmute(flags)
        };
        if !flags.is_empty() && groups.len() != flags.len() {
            return Err(Error::Configuration(ConfigurationError::InvalidParameters));
        }
        if has_duplicates(groups) {
            return Err(Error::Configuration(
                ConfigurationError::DuplicatedParameters,
            ));
        }

        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`
            if flags.is_empty() {
                bssl_sys::SSL_CTX_set1_group_ids(self.ptr(), groups.as_ffi_ptr(), groups.len())
            } else {
                bssl_sys::SSL_CTX_set1_group_ids_with_flags(
                    self.ptr(),
                    groups.as_ffi_ptr(),
                    flags.as_ffi_ptr(),
                    groups.len(),
                )
            }
        });
        Ok(self)
    }

    /// Set a list of cipher suites, in the order of descending preference.
    ///
    /// This method accepts a string that conforms to OpenSSL [cipher suite configuration] language
    /// specification.
    ///
    /// # Available cipher rules are:
    ///
    /// - `ALL` matches all ciphers, except for deprecated ciphers which must be
    ///   named explicitly.
    ///
    /// - `kRSA`, `kDHE`, `kECDHE`, and `kPSK` match ciphers using plain RSA, DHE,
    ///   ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is
    ///   matched by `kECDHE` and not `kPSK`.
    ///
    /// - `aRSA`, `aECDSA`, and `aPSK` match ciphers authenticated by RSA, ECDSA, and
    ///   a pre-shared key, respectively.
    ///
    /// - `RSA`, `DHE`, `ECDHE`, `PSK`, `ECDSA`, and `PSK` are aliases for the
    ///   corresponding `k*` or `a*` cipher rule. `RSA` is an alias for `kRSA`, not
    ///   `aRSA`.
    ///
    /// - `3DES`, `AES128`, `AES256`, `AES`, `AESGCM`, `CHACHA20` match ciphers
    ///   whose bulk cipher use the corresponding encryption scheme. Note that
    ///   `AES`, `AES128`, and `AES256` match both CBC and GCM ciphers.
    ///
    /// - `SHA1`, and its alias `SHA`, match legacy cipher suites using HMAC-SHA1.
    ///
    /// # Deprecated cipher rules:
    ///
    /// - `kEDH`, `EDH`, `kEECDH`, and `EECDH` are legacy aliases for `kDHE`, `DHE`,
    ///   `kECDHE`, and `ECDHE`, respectively.
    ///
    /// - `HIGH` is an alias for `ALL`.
    ///
    /// - `FIPS` is an alias for `HIGH`.
    ///
    /// - `SSLv3` and `TLSv1` match ciphers available in TLS 1.1 or earlier.
    ///   `TLSv1_2` matches ciphers new in TLS 1.2. This is confusing and should not
    ///   be used.
    ///
    /// [cipher suite configuration]: <https://docs.openssl.org/3.0/man1/openssl-ciphers/#cipher-list-format>
    pub fn with_ciphers(&mut self, cipher_ops: &str) -> Result<&mut Self, Error> {
        let Ok(cipher_ops) = alloc::ffi::CString::new(cipher_ops) else {
            return Err(Error::Configuration(ConfigurationError::InvalidString));
        };
        check_lib_error!(unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`;
            // - the string has been checked for internal NUL bytes and NUL-terminated.
            bssl_sys::SSL_CTX_set_strict_cipher_list(self.ptr(), cipher_ops.as_ptr())
        });
        Ok(self)
    }

    /// Set TLS 1.2 session lifetime in seconds.
    ///
    /// If 0 seconds are specified, BoringSSL will pick a default timeout for the connections.
    pub fn with_tls12_timeout(&mut self, seconds: u32) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_set_timeout(self.ptr(), seconds)
        };
        self
    }

    /// Set TLS 1.3 session lifetime in seconds.
    ///
    /// If 0 seconds are specified, BoringSSL will pick a default timeout for the connections.
    pub fn with_tls13_timeout(&mut self, seconds: u32) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_set_session_psk_dhe_timeout(self.ptr(), seconds)
        };
        self
    }

    /// Set whether shutting down the connection sends out a `close_notify` alert.
    pub fn with_quiet_shutdown(&mut self, quiet: bool) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::SSL_CTX_set_quiet_shutdown(self.ptr(), if quiet { 1 } else { 0 });
        }
        self
    }
}

impl<M> Drop for TlsContextBuilder<M> {
    fn drop(&mut self) {
        unsafe {
            // Safety: self.0 is created from SSL_CTX_new so it is a valid pointer
            bssl_sys::SSL_CTX_free(self.ptr());
        }
    }
}

/// A TLS context that is finalised and can be shared across connections
pub struct TlsContext<M = TlsMode> {
    ptr: NonNull<bssl_sys::SSL_CTX>,
    cert_cache: Option<Arc<CertificateCache>>,
    _p: PhantomData<fn() -> M>,
}

impl<M> TlsContext<M> {
    pub(crate) fn ptr(&self) -> *mut bssl_sys::SSL_CTX {
        self.ptr.as_ptr()
    }
}

/// # Create new connections associated to a context
impl<M> TlsContext<M>
where
    M: HasTlsContextMethod + HasTlsConnectionMethod,
{
    fn new_connection(
        &self,
        compliance_policy: Option<CompliancePolicy>,
    ) -> NonNull<bssl_sys::SSL> {
        let conn = unsafe {
            // Safety: in this type-state, our SSL_CTX is effectively immutable,
            // so we can freely alias.
            bssl_sys::SSL_new(self.ptr())
        };
        if let Some(policy) = compliance_policy {
            unsafe {
                // Safety: `policy` is a valid enum value per construction.
                bssl_sys::SSL_set_compliance_policy(conn, policy as _);
            }
        }
        NonNull::new(conn).expect("allocation failure")
    }

    /// Make a new client-half connection inheriting the configuration of this context
    ///
    /// By default, this method will configure the connection to request certificates
    /// from the server.
    /// To override this default, use
    /// [`TlsConnectionBuilder::with_certificate_verification_mode`].
    pub fn new_client_connection(
        &self,
        compliance_policy: Option<CompliancePolicy>,
    ) -> Result<TlsConnectionBuilder<Client, M>, Error> {
        let conn = self.new_connection(compliance_policy);
        unsafe {
            // Safety: the connection is still valid here
            bssl_sys::SSL_set_connect_state(conn.as_ptr());
        }
        let mut builder = TlsConnectionBuilder::from_ssl(conn, self.cert_cache.clone());
        // The safe default is that the client should perform at least
        // some certification verification.
        builder.with_certificate_verification_mode(
            crate::credentials::CertificateVerificationMode::PeerCertRequested,
        );
        Ok(builder)
    }

    /// Make a new server-half connection inheriting the configuration of this context
    pub fn new_server_connection(
        &self,
        compliance_policy: Option<CompliancePolicy>,
    ) -> Result<TlsConnectionBuilder<Server, M>, Error> {
        let conn = self.new_connection(compliance_policy);
        unsafe {
            // Safety: the connection is still valid here
            bssl_sys::SSL_set_accept_state(conn.as_ptr());
        }
        Ok(TlsConnectionBuilder::from_ssl(
            conn,
            self.cert_cache.clone(),
        ))
    }

    /// Expose the fully built BoringSSL's `SSL_CTX` pointer.
    ///
    /// # Safety
    /// - `SSL_CTX` is **not fully thread-safe**; do not invoke any BoringSSL mutating functions
    ///   on the returned handle; otherwise, it is **undefined behaviour**.
    /// - interacting with the `ex_data` of the `SSL_CTX` instance that this method returns is
    ///   **undefined behaviour**.
    /// - `self` must outlive all uses of the returned handle;
    /// - this handle must be used with functions from the BoringSSL library this crate is linked
    ///   to; otherwise, it is **undefined behaviour**.
    ///
    /// # Recommendation
    /// If the handle is used to interface BoringSSL library functions, please consider using a
    /// corresponding Rust safe binding or contact BoringSSL Authors for support.
    pub unsafe fn as_mut_ptr(&mut self) -> *mut bssl_sys::SSL_CTX {
        self.ptr()
    }
}

/// Safety: at this type state, most of the underlying context is immutable,
/// while methods on shared accesses are protected behind a mutex, so they are thread-safe.
unsafe impl<M> Send for TlsContext<M> {}
unsafe impl<M> Sync for TlsContext<M> {}

impl<M> Drop for TlsContext<M> {
    fn drop(&mut self) {
        unsafe {
            // Safety: this handle is taken from the builder, so it must be
            // live and valid.
            bssl_sys::SSL_CTX_free(self.ptr());
        }
    }
}

impl<M> Clone for TlsContext<M> {
    fn clone(&self) -> Self {
        unsafe {
            // Safety: this handle is already valid by the witness of self.
            bssl_sys::SSL_CTX_up_ref(self.ptr());
            // BoringSSL will always return success on bumping reference.
        }
        TlsContext {
            ptr: self.ptr,
            cert_cache: self.cert_cache.clone(),
            _p: PhantomData,
        }
    }
}

/// A reusable certificate cache shared across [`TlsContext`]
pub struct CertificateCache(pub(crate) NonNull<bssl_sys::CRYPTO_BUFFER_POOL>);

// Safety: `CRYPTO_BUFFER_POOL` is mutex-protected
unsafe impl Send for CertificateCache {}
unsafe impl Sync for CertificateCache {}

impl CertificateCache {
    /// Construct a new certificate cache.
    pub fn new() -> Self {
        let pool = unsafe {
            // Safety: this call does not have side-effect other than allocation
            bssl_sys::CRYPTO_BUFFER_POOL_new()
        };
        Self(NonNull::new(pool).expect("allocation failure"))
    }

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

impl Drop for CertificateCache {
    fn drop(&mut self) {
        unsafe {
            // Safety: the validity of `self.0` is witnessed by `self`
            bssl_sys::CRYPTO_BUFFER_POOL_free(self.0.as_ptr());
        }
    }
}
