//! Querying trust settings.

use core_foundation::array::{CFArray, CFArrayRef};
use core_foundation::base::{CFIndex, TCFType};
use core_foundation::dictionary::CFDictionary;
use core_foundation::number::CFNumber;
use core_foundation::string::CFString;

use security_framework_sys::base::errSecNoTrustSettings;
use security_framework_sys::base::errSecSuccess;
use security_framework_sys::trust_settings::*;

use std::ptr;

use crate::base::Error;
use crate::base::Result;
use crate::certificate::SecCertificate;
use crate::cvt;

/// Which set of trust settings to query
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Domain {
    /// Per-user trust settings
    User,
    /// Locally administered, system-wide trust settings
    Admin,
    /// System trust settings
    System,
}

impl From<Domain> for SecTrustSettingsDomain {
    #[inline]
    fn from(domain: Domain) -> SecTrustSettingsDomain {
        match domain {
            Domain::User => kSecTrustSettingsDomainUser,
            Domain::Admin => kSecTrustSettingsDomainAdmin,
            Domain::System => kSecTrustSettingsDomainSystem,
        }
    }
}

/// Trust settings for a specific certificate in a specific domain
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum TrustSettingsForCertificate {
    /// Not used
    Invalid,

    /// This is a root certificate and is trusted, either explicitly or
    /// implicitly.
    TrustRoot,

    /// This is a non-root certificate but is explicitly trusted.
    TrustAsRoot,

    /// Cert is explicitly distrusted.
    Deny,

    /// Neither trusted nor distrusted.
    Unspecified,
}

impl TrustSettingsForCertificate {
    /// Create from `kSecTrustSettingsResult*` constant
    fn new(value: i64) -> Self {
        if value < 0 || value > i64::from(u32::max_value()) {
            return Self::Invalid;
        }
        match value as u32 {
            kSecTrustSettingsResultTrustRoot => Self::TrustRoot,
            kSecTrustSettingsResultTrustAsRoot => Self::TrustAsRoot,
            kSecTrustSettingsResultDeny => Self::Deny,
            kSecTrustSettingsResultUnspecified => Self::Unspecified,
            _ => Self::Invalid,
        }
    }
}

/// Allows access to the certificates and their trust settings in a given domain.
pub struct TrustSettings {
    domain: Domain,
}

impl TrustSettings {
    /// Create a new `TrustSettings` for the given domain.
    ///
    /// You can call `iter()` to discover the certificates with settings in this domain.
    ///
    /// Then you can call `tls_trust_settings_for_certificate()` with a given certificate
    /// to learn what the aggregate trust setting for that certificate within this domain.
    #[inline(always)]
    #[must_use] pub fn new(domain: Domain) -> Self {
        Self { domain }
    }

    /// Create an iterator over the certificates with settings in this domain.
    /// This produces an empty iterator if there are no such certificates.
    pub fn iter(&self) -> Result<TrustSettingsIter> {
        let array = unsafe {
            let mut array_ptr: CFArrayRef = ptr::null_mut();

            // SecTrustSettingsCopyCertificates returns errSecNoTrustSettings
            // if no items have trust settings in the given domain.  We map
            // that to an empty TrustSettings iterator.
            match SecTrustSettingsCopyCertificates(self.domain.into(), &mut array_ptr) {
                errSecNoTrustSettings => CFArray::from_CFTypes(&[]),
                errSecSuccess => CFArray::<SecCertificate>::wrap_under_create_rule(array_ptr),
                err => return Err(Error::from_code(err)),
            }
        };

        Ok(TrustSettingsIter { index: 0, array })
    }

    /// Returns the aggregate trust setting for the given certificate.
    ///
    /// This tells you whether the certificate should be trusted as a TLS
    /// root certificate.
    ///
    /// If the certificate has no trust settings in the given domain, the
    /// `errSecItemNotFound` error is returned.
    ///
    /// If the certificate has no specific trust settings for TLS in the
    /// given domain `None` is returned.
    ///
    /// Otherwise, the specific trust settings are aggregated and returned.
    pub fn tls_trust_settings_for_certificate(&self, cert: &SecCertificate)
        -> Result<Option<TrustSettingsForCertificate>> {
        let trust_settings = unsafe {
            let mut array_ptr: CFArrayRef = ptr::null_mut();
            let cert_ptr = cert.as_CFTypeRef() as *mut _;
            cvt(SecTrustSettingsCopyTrustSettings(cert_ptr,
                                                  self.domain.into(),
                                                  &mut array_ptr))?;
            CFArray::<CFDictionary>::wrap_under_create_rule(array_ptr)
        };

        for settings in trust_settings.iter() {
            // Reject settings for non-SSL policies
            let is_not_ssl_policy = {
                let policy_name_key = CFString::from_static_string("kSecTrustSettingsPolicyName");
                let ssl_policy_name = CFString::from_static_string("sslServer");

                let maybe_name: Option<CFString> = settings
                    .find(policy_name_key.as_CFTypeRef().cast())
                    .map(|name| unsafe { CFString::wrap_under_get_rule((*name).cast()) });

                matches!(maybe_name, Some(ref name) if name != &ssl_policy_name)
            };

            if is_not_ssl_policy {
                continue;
            }

            // Evaluate "effective trust settings" for this usage constraint.
            let maybe_trust_result = {
                let settings_result_key = CFString::from_static_string("kSecTrustSettingsResult");
                settings
                    .find(settings_result_key.as_CFTypeRef().cast())
                    .map(|num| unsafe { CFNumber::wrap_under_get_rule((*num).cast()) })
                    .and_then(|num| num.to_i64())
            };

            // "Note that an empty Trust Settings array means "always trust this cert,
            //  with a resulting kSecTrustSettingsResult of kSecTrustSettingsResultTrustRoot"."
            let trust_result = TrustSettingsForCertificate::new(maybe_trust_result
                .unwrap_or_else(|| i64::from(kSecTrustSettingsResultTrustRoot)));

            match trust_result {
                TrustSettingsForCertificate::Unspecified |
                TrustSettingsForCertificate::Invalid => { continue; },
                _ => return Ok(Some(trust_result)),
            }
        }

        // There were no more specific settings.  This might mean the certificate
        // is to be trusted anyway (since, eg, it's in system store), but leave
        // the caller to make this decision.
        Ok(None)
    }
}

/// Iterator over certificates.
pub struct TrustSettingsIter {
    array: CFArray<SecCertificate>,
    index: CFIndex,
}

impl Iterator for TrustSettingsIter {
    type Item = SecCertificate;

    #[inline]
    fn next(&mut self) -> Option<Self::Item> {
        if self.index >= self.array.len() {
            None
        } else {
            let cert = self.array.get(self.index).unwrap();
            self.index += 1;
            Some(cert.clone())
        }
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        let left = (self.array.len() as usize).saturating_sub(self.index as usize);
        (left, Some(left))
    }
}

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

    fn list_for_domain(domain: Domain) {
        println!("--- domain: {:?}", domain);
        let ts = TrustSettings::new(domain);
        let iterator = ts.iter().unwrap();

        for (i, cert) in iterator.enumerate() {
            println!("cert({:?}) = {:?}", i, cert);
            println!("  settings = {:?}", ts.tls_trust_settings_for_certificate(&cert));
        }
        println!("---");
    }

    #[test]
    fn list_for_user() {
        list_for_domain(Domain::User);
    }

    #[test]
    fn list_for_system() {
        list_for_domain(Domain::System);
    }

    #[test]
    fn list_for_admin() {
        list_for_domain(Domain::Admin);
    }

    #[test]
    fn test_system_certs_are_present() {
        let system = TrustSettings::new(Domain::System).iter().unwrap().count();

        // 168 at the time of writing
        assert!(system > 100);
    }

    #[test]
    fn test_isrg_root_exists_and_is_trusted() {
        let ts = TrustSettings::new(Domain::System);
        assert_eq!(ts
            .iter()
            .unwrap()
            .find(|cert| cert.subject_summary() == "ISRG Root X1")
            .and_then(|cert| ts.tls_trust_settings_for_certificate(&cert).unwrap()),
            None);
        // ^ this is a case where None means "always trust", according to Apple docs:
        //
        // "Note that an empty Trust Settings array means "always trust this cert,
        //  with a resulting kSecTrustSettingsResult of kSecTrustSettingsResultTrustRoot"."
    }

    #[test]
    fn test_unknown_cert_is_not_trusted() {
        let ts = TrustSettings::new(Domain::System);
        let cert = certificate();
        assert_eq!(ts.tls_trust_settings_for_certificate(&cert)
                   .err()
                   .unwrap()
                   .message(),
                   Some("The specified item could not be found in the keychain.".into()));
    }
}
