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

//! X.509 certificate verification parameters.

use alloc::ffi::CString;
use core::{
    ffi::{c_int, c_uint, c_ulong},
    ptr::NonNull,
};

use bssl_macros::bssl_enum;

use crate::{check_lib_error, errors::PkiError, ffi::slice_into_ffi_raw_parts};

bssl_enum! {
    /// Trust settings for certificate verification.
    #[derive(Clone, Copy, PartialEq, Eq)]
    pub enum Trust: i8 {
        /// Compatibility mode.
        Compat = bssl_sys::X509_TRUST_COMPAT as i8,
        /// Trust as a client SSL certificate.
        SslClient = bssl_sys::X509_TRUST_SSL_CLIENT as i8,
        /// Trust as a server SSL certificate.
        SslServer = bssl_sys::X509_TRUST_SSL_SERVER as i8,
        /// Trust as an email certificate.
        Email = bssl_sys::X509_TRUST_EMAIL as i8,
        /// Trust as an object signing certificate.
        ObjectSign = bssl_sys::X509_TRUST_OBJECT_SIGN as i8,
        /// Trust as a Time Stamping Authority.
        Tsa = bssl_sys::X509_TRUST_TSA as i8,
    }
}

bssl_enum! {
    /// Purpose settings for certificate verification.
    #[derive(Clone, Copy, PartialEq, Eq)]
    pub enum Purpose: i8 {
        /// SSL client.
        SslClient = bssl_sys::X509_PURPOSE_SSL_CLIENT as i8,
        /// SSL server.
        SslServer = bssl_sys::X509_PURPOSE_SSL_SERVER as i8,
        /// Netscape SSL server.
        NsSslServer = bssl_sys::X509_PURPOSE_NS_SSL_SERVER as i8,
        /// S/MIME signing.
        SmimeSign = bssl_sys::X509_PURPOSE_SMIME_SIGN as i8,
        /// S/MIME encryption.
        SmimeEncrypt = bssl_sys::X509_PURPOSE_SMIME_ENCRYPT as i8,
        /// CRL signing.
        CrlSign = bssl_sys::X509_PURPOSE_CRL_SIGN as i8,
        /// Any purpose.
        Any = bssl_sys::X509_PURPOSE_ANY as i8,
        /// OCSP helper.
        OcspHelper = bssl_sys::X509_PURPOSE_OCSP_HELPER as i8,
        /// Timestamp signing.
        TimestampSign = bssl_sys::X509_PURPOSE_TIMESTAMP_SIGN as i8,
    }
}

bitflags::bitflags! {
    /// Flags for X.509 certificate verification.
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct VerificationFlags: c_ulong {
        /// Use check time.
        const USE_CHECK_TIME = bssl_sys::X509_V_FLAG_USE_CHECK_TIME as c_ulong;
        /// Explicit policy, which mandates assertions of the policy OIDs in the final certificate
        /// chain.
        ///
        /// See [RFC 5280], §6.1.1.
        ///
        /// [RFC 5280]: <https://datatracker.ietf.org/doc/html/rfc5280#section-6.1.1>
        const EXPLICIT_POLICY = bssl_sys::X509_V_FLAG_EXPLICIT_POLICY as c_ulong;
        /// Inhibit the `anyPolicy`.
        ///
        /// See [RFC 5280], §6.1.1.
        ///
        /// [RFC 5280]: <https://datatracker.ietf.org/doc/html/rfc5280#section-6.1.1>
        const INHIBIT_ANY = bssl_sys::X509_V_FLAG_INHIBIT_ANY as c_ulong;
        /// Inhibit policy mapping.
        ///
        /// See [RFC 5280], §6.1.1.
        ///
        /// [RFC 5280]: <https://datatracker.ietf.org/doc/html/rfc5280#section-6.1.1>
        const INHIBIT_MAP = bssl_sys::X509_V_FLAG_INHIBIT_MAP as c_ulong;
        /// Treat all trusted certificates as trust anchors regardless of the
        /// [`CertificateVerificationParams::set_trust`] setting.
        const PARTIAL_CHAIN = bssl_sys::X509_V_FLAG_PARTIAL_CHAIN as c_ulong;
        /// Disable building of alternative chains, when the first built chain was rejected.
        const NO_ALT_CHAINS = bssl_sys::X509_V_FLAG_NO_ALT_CHAINS as c_ulong;
        /// Disable all time checks during certificate verification.
        const NO_CHECK_TIME = bssl_sys::X509_V_FLAG_NO_CHECK_TIME as c_ulong;
    }
}

bitflags::bitflags! {
    /// Flags for X.509 host checking.
    #[derive(Debug, Copy, Clone, PartialEq, Eq)]
    pub struct HostFlags: c_uint {
        /// Disable wildcard matching for DNS names.
        const NO_WILDCARDS = bssl_sys::X509_CHECK_FLAG_NO_WILDCARDS as c_uint;
        /// Disable the subject fallback, normally enabled when subjectAltNames is missing.
        const NEVER_CHECK_SUBJECT = bssl_sys::X509_CHECK_FLAG_NEVER_CHECK_SUBJECT as c_uint;
    }
}

/// X.509 verification parameters.
pub struct CertificateVerificationParams(NonNull<bssl_sys::X509_VERIFY_PARAM>);

// Safety:
// - `X509_VERIFY_PARAM` is a configuration struct and can be sent.
// - There are no methods that uses shared access, so no data race is possible.
unsafe impl Send for CertificateVerificationParams {}
unsafe impl Sync for CertificateVerificationParams {}

impl Drop for CertificateVerificationParams {
    fn drop(&mut self) {
        unsafe {
            bssl_sys::X509_VERIFY_PARAM_free(self.0.as_ptr());
        }
    }
}

impl CertificateVerificationParams {
    /// Create a new `CertificateVerificationParams`.
    pub fn new() -> Self {
        let param = unsafe {
            // Safety: this call returns a new X509_VERIFY_PARAM or null on failure.
            bssl_sys::X509_VERIFY_PARAM_new()
        };
        let Some(param) = NonNull::new(param) else {
            panic!("allocation error")
        };
        Self(param)
    }

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

    /// Extract the handle for cross-language interoperability.
    ///
    /// # Safety
    ///
    /// The handle **must** outlive the use sites.
    /// Verify the callsite contract to honour the lifetime contracts.
    pub unsafe fn as_raw(&self) -> *mut bssl_sys::X509_VERIFY_PARAM {
        self.ptr()
    }

    /// Set the expected DNS hostname.
    pub fn set_host(&mut self, host: &str) -> Result<&mut Self, PkiError> {
        let c_host = CString::new(host).map_err(|_| PkiError::InternalNullBytes)?;
        check_lib_error!(unsafe {
            // Safety: the string has been NUL-terminated.
            bssl_sys::X509_VERIFY_PARAM_set1_host(self.ptr(), c_host.as_ptr(), host.len())
        });
        Ok(self)
    }

    /// Add an expected DNS hostname.
    pub fn add_host(&mut self, host: &str) -> Result<&mut Self, PkiError> {
        let c_host = CString::new(host).map_err(|_| PkiError::InternalNullBytes)?;
        check_lib_error!(unsafe {
            // Safety: the string has been NUL-terminated.
            bssl_sys::X509_VERIFY_PARAM_add1_host(self.ptr(), c_host.as_ptr(), host.len())
        });
        Ok(self)
    }

    /// Set the expected email address.
    pub fn set_email(&mut self, email: &str) -> Result<&mut Self, PkiError> {
        let c_email = CString::new(email).map_err(|_| PkiError::InternalNullBytes)?;
        check_lib_error!(unsafe {
            bssl_sys::X509_VERIFY_PARAM_set1_email(self.ptr(), c_email.as_ptr(), email.len())
        });

        Ok(self)
    }

    /// Set the expected IP address.
    pub fn set_ip(&mut self, ip: &[u8]) -> Result<&mut Self, PkiError> {
        if !matches!(ip.len(), 4 | 16) {
            return Err(PkiError::InvalidIp);
        }
        let (ip, len) = slice_into_ffi_raw_parts(ip);
        check_lib_error!(unsafe {
            // Safety: the slice pointer is not null.
            bssl_sys::X509_VERIFY_PARAM_set1_ip(self.ptr(), ip, len)
        });

        Ok(self)
    }

    /// Set the expected IP address from an ASCII string.
    pub fn set_ip_asc(&mut self, ip: &str) -> Result<&mut Self, PkiError> {
        let c_ip = CString::new(ip).map_err(|_| PkiError::InvalidIp)?;
        check_lib_error!(unsafe {
            // Safety: the string has been NUL-terminated.
            bssl_sys::X509_VERIFY_PARAM_set1_ip_asc(self.ptr(), c_ip.as_ptr())
        });

        Ok(self)
    }

    /// Set the verification depth.
    pub fn set_depth(&mut self, depth: u16) -> &mut Self {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::X509_VERIFY_PARAM_set_depth(self.ptr(), depth.into());
        }
        self
    }

    /// Set the verification purpose.
    pub fn set_purpose(&mut self, purpose: Purpose) -> Result<&mut Self, PkiError> {
        check_lib_error!(unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - the `purpose` value is valid per construction.
            bssl_sys::X509_VERIFY_PARAM_set_purpose(self.ptr(), purpose as c_int)
        });
        Ok(self)
    }

    /// Set the verification trust.
    pub fn set_trust(&mut self, trust: Trust) -> Result<&mut Self, PkiError> {
        check_lib_error!(unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::X509_VERIFY_PARAM_set_trust(self.ptr(), trust as c_int)
        });
        Ok(self)
    }

    /// Set time that verification will run against, specified as Unix timestamp.
    pub fn set_time_posix(&mut self, time: i64) {
        unsafe {
            // Safety: the validity of the handle `self.0` is witnessed by `self`.
            bssl_sys::X509_VERIFY_PARAM_set_time_posix(self.ptr(), time);
        }
    }

    /// Set verification flags.
    pub fn set_flags(&mut self, flags: VerificationFlags) -> Result<&mut Self, PkiError> {
        check_lib_error!(unsafe {
            // Safety: the flag bits are valid by construction.
            bssl_sys::X509_VERIFY_PARAM_set_flags(self.ptr(), flags.bits())
        });
        Ok(self)
    }

    /// Clear verification flags.
    pub fn clear_flags(&mut self, flags: VerificationFlags) -> Result<&mut Self, PkiError> {
        check_lib_error!(unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - the flag bits are valid by construction.
            bssl_sys::X509_VERIFY_PARAM_clear_flags(self.ptr(), flags.bits())
        });
        Ok(self)
    }

    /// Set the host flags.
    pub fn set_hostflags(&mut self, flags: HostFlags) {
        unsafe {
            // Safety:
            // - the validity of the handle `self.0` is witnessed by `self`.
            // - the flag bits are valid by construction.
            bssl_sys::X509_VERIFY_PARAM_set_hostflags(self.ptr(), flags.bits());
        }
    }
}
