#![allow(
    non_upper_case_globals,
    non_camel_case_types,
    non_snake_case,
    dead_code,
    clippy::pedantic,
    clippy::restriction,
    clippy::all
)]

include!(concat!(env!("OUT_DIR"), "/ossl_bindings.rs"));

/// Non-public OpenSSL internals required to implement a FIPS provider.
///
/// Only available with the `fips-provider` cargo feature.  The types here
/// give direct access to the `EVP_SIGNATURE` vtable struct and the `evp_pkey_st`
/// internals needed to invoke signature function pointers without going through
/// the high-level `EVP_DigestSign*` API (which is unavailable inside a FIPS
/// provider due to circular provider dependencies).
#[cfg(feature = "fips-provider")]
pub mod fips_internal {
    #![allow(
        non_upper_case_globals,
        non_camel_case_types,
        non_snake_case,
        dead_code,
        clippy::all
    )]
    include!(concat!(env!("OUT_DIR"), "/fips_bindings.rs"));
    include!(concat!(env!("OUT_DIR"), "/keydata_offset.rs"));
}

#[cfg(test)]
mod tests {
    use super::*;

    /// Smoke-test: confirm that key opaque types are bound and reachable.
    #[test]
    fn opaque_type_sizes_are_nonzero() {
        // Opaque structs are represented as zero-sized types in bindgen output,
        // but the pointer sizes must be word-sized on this platform.
        assert_eq!(
            std::mem::size_of::<*mut EVP_MD>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_MD_CTX>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_CIPHER>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_CIPHER_CTX>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_MAC>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_MAC_CTX>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_PKEY>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut EVP_PKEY_CTX>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut X509>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut SSL_CTX>(),
            std::mem::size_of::<usize>()
        );
        assert_eq!(
            std::mem::size_of::<*mut SSL>(),
            std::mem::size_of::<usize>()
        );
    }

    /// Confirm that OPENSSL_VERSION_NUMBER is >= 3.5.0 (enforced by build.rs too,
    /// but this makes the requirement visible at test time).
    #[test]
    fn openssl_version_at_least_3_5_0() {
        // OPENSSL_VERSION_NUMBER is included via the bindings.
        // 3.5.0 = 0x3050_0000
        assert!(OPENSSL_VERSION_NUMBER >= 0x3050_0000);
    }
}
