//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::cell::UnsafeCell;
use core::ffi::*;
use core::marker::{PhantomData, PhantomPinned};
use core::ptr::NonNull;
#[cfg(feature = "dispatch2")]
use dispatch2::*;
#[cfg(feature = "objc2")]
use objc2::__framework_prelude::*;
use objc2_core_foundation::*;

use crate::*;

/// This is the handle to a network address or name.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/systemconfiguration/scnetworkreachability?language=objc)
#[doc(alias = "SCNetworkReachabilityRef")]
#[repr(C)]
pub struct SCNetworkReachability {
    inner: [u8; 0],
    _p: UnsafeCell<PhantomData<(*const UnsafeCell<()>, PhantomPinned)>>,
}

cf_type!(
    unsafe impl SCNetworkReachability {}
);
#[cfg(feature = "objc2")]
cf_objc2_type!(
    unsafe impl RefEncode<"__SCNetworkReachability"> for SCNetworkReachability {}
);

/// Structure containing user-specified data and callbacks for SCNetworkReachability.
/// Field: version The version number of the structure type being passed
/// in as a parameter to the SCDynamicStore creation function.
/// This structure is version 0.
/// Field: info A C pointer to a user-specified block of data.
/// Field: retain The callback used to add a retain for the info field.
/// If this parameter is not a pointer to a function of the correct
/// prototype, the behavior is undefined.  The value may be NULL.
/// Field: release The calllback used to remove a retain previously added
/// for the info field.  If this parameter is not a pointer to a
/// function of the correct prototype, the behavior is undefined.
/// The value may be NULL.
/// Field: copyDescription The callback used to provide a description of
/// the info field.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/systemconfiguration/scnetworkreachabilitycontext?language=objc)
#[repr(C)]
#[allow(unpredictable_function_pointer_comparisons)]
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct SCNetworkReachabilityContext {
    pub version: CFIndex,
    pub info: *mut c_void,
    pub retain: Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> NonNull<c_void>>,
    pub release: Option<unsafe extern "C-unwind" fn(NonNull<c_void>)>,
    pub copyDescription: Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> NonNull<CFString>>,
}

#[cfg(feature = "objc2")]
unsafe impl Encode for SCNetworkReachabilityContext {
    const ENCODING: Encoding = Encoding::Struct(
        "?",
        &[
            <CFIndex>::ENCODING,
            <*mut c_void>::ENCODING,
            <Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> NonNull<c_void>>>::ENCODING,
            <Option<unsafe extern "C-unwind" fn(NonNull<c_void>)>>::ENCODING,
            <Option<unsafe extern "C-unwind" fn(NonNull<c_void>) -> NonNull<CFString>>>::ENCODING,
        ],
    );
}

#[cfg(feature = "objc2")]
unsafe impl RefEncode for SCNetworkReachabilityContext {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Flags that indicate whether the specified network
/// nodename or address is reachable, whether a connection is
/// required, and whether some user intervention may be required
/// when establishing a connection.
///
/// This flag indicates that the specified nodename or address can
/// be reached via a transient connection, such as PPP.
///
/// This flag indicates that the specified nodename or address can
/// be reached using the current network configuration.
///
/// This flag indicates that the specified nodename or address can
/// be reached using the current network configuration, but a
/// connection must first be established.
///
/// As an example, this status would be returned for a dialup
/// connection that was not currently active, but could handle
/// network traffic for the target system.
///
/// This flag indicates that the specified nodename or address can
/// be reached using the current network configuration, but a
/// connection must first be established.  Any traffic directed
/// to the specified name or address will initiate the connection.
///
/// Note: this flag was previously named kSCNetworkReachabilityFlagsConnectionAutomatic
///
/// This flag indicates that the specified nodename or address can
/// be reached using the current network configuration, but a
/// connection must first be established.  In addition, some
/// form of user intervention will be required to establish this
/// connection, such as providing a password, an authentication
/// token, etc.
///
/// Note: At the present time, this flag will only be returned
/// in the case where you have a dial-on-traffic configuration
/// (ConnectionOnTraffic), where an attempt to connect has
/// already been made, and where some error (e.g. no dial tone,
/// no answer, bad password, ...) was encountered during the
/// automatic connection attempt.  In this case the PPP controller
/// will stop attempting to establish a connection until the user
/// has intervened.
///
/// This flag indicates that the specified nodename or address can
/// be reached using the current network configuration, but a
/// connection must first be established.
/// The connection will be established "On Demand" by the
/// CFSocketStream APIs.
/// Other APIs will not establish the connection.
///
/// This flag indicates that the specified nodename or address
/// is one associated with a network interface on the current
/// system.
///
/// This flag indicates that network traffic to the specified
/// nodename or address will not go through a gateway, but is
/// routed directly to one of the interfaces in the system.
///
/// This flag indicates that the specified nodename or address can
/// be reached via an EDGE, GPRS, or other "cell" connection.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/systemconfiguration/scnetworkreachabilityflags?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct SCNetworkReachabilityFlags(pub u32);
bitflags::bitflags! {
    impl SCNetworkReachabilityFlags: u32 {
        #[doc(alias = "kSCNetworkReachabilityFlagsTransientConnection")]
        const TransientConnection = 1<<0;
        #[doc(alias = "kSCNetworkReachabilityFlagsReachable")]
        const Reachable = 1<<1;
        #[doc(alias = "kSCNetworkReachabilityFlagsConnectionRequired")]
        const ConnectionRequired = 1<<2;
        #[doc(alias = "kSCNetworkReachabilityFlagsConnectionOnTraffic")]
        const ConnectionOnTraffic = 1<<3;
        #[doc(alias = "kSCNetworkReachabilityFlagsInterventionRequired")]
        const InterventionRequired = 1<<4;
        #[doc(alias = "kSCNetworkReachabilityFlagsConnectionOnDemand")]
        const ConnectionOnDemand = 1<<5;
        #[doc(alias = "kSCNetworkReachabilityFlagsIsLocalAddress")]
        const IsLocalAddress = 1<<16;
        #[doc(alias = "kSCNetworkReachabilityFlagsIsDirect")]
        const IsDirect = 1<<17;
        #[doc(alias = "kSCNetworkReachabilityFlagsIsWWAN")]
        const IsWWAN = 1<<18;
        #[doc(alias = "kSCNetworkReachabilityFlagsConnectionAutomatic")]
        const ConnectionAutomatic = SCNetworkReachabilityFlags::ConnectionOnTraffic.0;
    }
}

#[cfg(feature = "objc2")]
unsafe impl Encode for SCNetworkReachabilityFlags {
    const ENCODING: Encoding = u32::ENCODING;
}

#[cfg(feature = "objc2")]
unsafe impl RefEncode for SCNetworkReachabilityFlags {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Type of the callback function used when the
/// reachability of a network address or name changes.
///
/// Parameter `target`: The SCNetworkReachability reference being monitored
/// for changes.
///
/// Parameter `flags`: The new SCNetworkReachabilityFlags representing the
/// reachability status of the network address/name.
///
/// Parameter `info`: A C pointer to a user-specified block of data.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/systemconfiguration/scnetworkreachabilitycallback?language=objc)
pub type SCNetworkReachabilityCallBack = Option<
    unsafe extern "C-unwind" fn(
        NonNull<SCNetworkReachability>,
        SCNetworkReachabilityFlags,
        *mut c_void,
    ),
>;

impl SCNetworkReachability {
    /// Creates a reference to the specified network
    /// address.  This reference can be used later to monitor the
    /// reachability of the target host.
    ///
    /// Parameter `address`: The address of the desired host.
    ///
    /// Returns: Returns a reference to the new immutable SCNetworkReachabilityRef.
    ///
    /// You must release the returned value.
    ///
    /// # Safety
    ///
    /// `address` must be a valid pointer.
    #[doc(alias = "SCNetworkReachabilityCreateWithAddress")]
    #[cfg(feature = "libc")]
    #[deprecated]
    #[inline]
    pub unsafe fn with_address(
        allocator: Option<&CFAllocator>,
        address: NonNull<libc::sockaddr>,
    ) -> Option<CFRetained<SCNetworkReachability>> {
        extern "C-unwind" {
            fn SCNetworkReachabilityCreateWithAddress(
                allocator: Option<&CFAllocator>,
                address: NonNull<libc::sockaddr>,
            ) -> Option<NonNull<SCNetworkReachability>>;
        }
        let ret = unsafe { SCNetworkReachabilityCreateWithAddress(allocator, address) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// Creates a reference to the specified network
    /// address.  This reference can be used later to monitor the
    /// reachability of the target host.
    ///
    /// Parameter `localAddress`: The local address associated with a network
    /// connection.  If NULL, only the remote address is of interest.
    ///
    /// Parameter `remoteAddress`: The remote address associated with a network
    /// connection.  If NULL, only the local address is of interest.
    ///
    /// Returns: Returns a reference to the new immutable SCNetworkReachabilityRef.
    ///
    /// You must release the returned value.
    ///
    /// # Safety
    ///
    /// - `local_address` must be a valid pointer or null.
    /// - `remote_address` must be a valid pointer or null.
    #[doc(alias = "SCNetworkReachabilityCreateWithAddressPair")]
    #[cfg(feature = "libc")]
    #[deprecated]
    #[inline]
    pub unsafe fn with_address_pair(
        allocator: Option<&CFAllocator>,
        local_address: *const libc::sockaddr,
        remote_address: *const libc::sockaddr,
    ) -> Option<CFRetained<SCNetworkReachability>> {
        extern "C-unwind" {
            fn SCNetworkReachabilityCreateWithAddressPair(
                allocator: Option<&CFAllocator>,
                local_address: *const libc::sockaddr,
                remote_address: *const libc::sockaddr,
            ) -> Option<NonNull<SCNetworkReachability>>;
        }
        let ret = unsafe {
            SCNetworkReachabilityCreateWithAddressPair(allocator, local_address, remote_address)
        };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }

    /// Creates a reference to the specified network host or node
    /// name.  This reference can be used later to monitor the
    /// reachability of the target host.
    ///
    /// Parameter `nodename`: The node name of the desired host.
    /// This name would be the same as that passed to the
    /// gethostbyname(3) or getaddrinfo(3) functions.
    ///
    /// Returns: Returns a reference to the new immutable SCNetworkReachabilityRef.
    ///
    /// You must release the returned value.
    ///
    /// # Safety
    ///
    /// `nodename` must be a valid pointer.
    #[doc(alias = "SCNetworkReachabilityCreateWithName")]
    #[deprecated]
    #[inline]
    pub unsafe fn with_name(
        allocator: Option<&CFAllocator>,
        nodename: NonNull<c_char>,
    ) -> Option<CFRetained<SCNetworkReachability>> {
        extern "C-unwind" {
            fn SCNetworkReachabilityCreateWithName(
                allocator: Option<&CFAllocator>,
                nodename: NonNull<c_char>,
            ) -> Option<NonNull<SCNetworkReachability>>;
        }
        let ret = unsafe { SCNetworkReachabilityCreateWithName(allocator, nodename) };
        ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
    }
}

unsafe impl ConcreteType for SCNetworkReachability {
    /// Returns the type identifier of all SCNetworkReachability
    /// instances.
    #[doc(alias = "SCNetworkReachabilityGetTypeID")]
    #[inline]
    fn type_id() -> CFTypeID {
        extern "C-unwind" {
            fn SCNetworkReachabilityGetTypeID() -> CFTypeID;
        }
        unsafe { SCNetworkReachabilityGetTypeID() }
    }
}

impl SCNetworkReachability {
    /// Determines if the given target is reachable using the
    /// current network configuration.
    ///
    /// Parameter `target`: The network reference associated with the address or name
    /// to be checked for reachability.
    ///
    /// Parameter `flags`: A pointer to memory that will be filled with the
    /// SCNetworkReachabilityFlags detailing the reachability
    /// of the specified target.
    ///
    /// Returns: Returns TRUE if the network connection flags are valid;
    /// FALSE if the status could not be determined.
    ///
    /// # Safety
    ///
    /// `flags` must be a valid pointer.
    #[doc(alias = "SCNetworkReachabilityGetFlags")]
    #[deprecated]
    #[inline]
    pub unsafe fn flags(&self, flags: NonNull<SCNetworkReachabilityFlags>) -> bool {
        extern "C-unwind" {
            fn SCNetworkReachabilityGetFlags(
                target: &SCNetworkReachability,
                flags: NonNull<SCNetworkReachabilityFlags>,
            ) -> Boolean;
        }
        let ret = unsafe { SCNetworkReachabilityGetFlags(self, flags) };
        ret != 0
    }

    /// Assigns a client to a target, which receives callbacks
    /// when the reachability of the target changes.
    ///
    /// Parameter `target`: The network reference associated with the address or
    /// name to be checked for reachability.
    ///
    /// Parameter `callout`: The function to be called when the reachability of the
    /// target changes.  If NULL, the current client for the target
    /// is removed.
    ///
    /// Parameter `context`: The SCNetworkReachabilityContext associated with
    /// the callout.  The value may be NULL.
    ///
    /// Returns: Returns TRUE if the notification client was successfully set.
    ///
    /// # Safety
    ///
    /// - `callout` must be implemented correctly.
    /// - `context` must be a valid pointer or null.
    #[doc(alias = "SCNetworkReachabilitySetCallback")]
    #[deprecated]
    #[inline]
    pub unsafe fn set_callback(
        &self,
        callout: SCNetworkReachabilityCallBack,
        context: *mut SCNetworkReachabilityContext,
    ) -> bool {
        extern "C-unwind" {
            fn SCNetworkReachabilitySetCallback(
                target: &SCNetworkReachability,
                callout: SCNetworkReachabilityCallBack,
                context: *mut SCNetworkReachabilityContext,
            ) -> Boolean;
        }
        let ret = unsafe { SCNetworkReachabilitySetCallback(self, callout, context) };
        ret != 0
    }

    /// Schedules the given target with the given run loop and mode.
    ///
    /// Parameter `target`: The address or name that is set up for asynchronous
    /// notifications.  Must be non-NULL.
    ///
    /// Parameter `runLoop`: A reference to a run loop on which the target should
    /// be scheduled.  Must be non-NULL.
    ///
    /// Parameter `runLoopMode`: The mode on which to schedule the target.
    /// Must be non-NULL.
    ///
    /// Returns: Returns TRUE if the target is scheduled successfully;
    /// FALSE otherwise.
    #[doc(alias = "SCNetworkReachabilityScheduleWithRunLoop")]
    #[deprecated]
    #[inline]
    pub fn schedule_with_run_loop(&self, run_loop: &CFRunLoop, run_loop_mode: &CFString) -> bool {
        extern "C-unwind" {
            fn SCNetworkReachabilityScheduleWithRunLoop(
                target: &SCNetworkReachability,
                run_loop: &CFRunLoop,
                run_loop_mode: &CFString,
            ) -> Boolean;
        }
        let ret =
            unsafe { SCNetworkReachabilityScheduleWithRunLoop(self, run_loop, run_loop_mode) };
        ret != 0
    }

    /// Unschedules the given target from the given run loop
    /// and mode.
    ///
    /// Parameter `target`: The address or name that is set up for asynchronous
    /// notifications.  Must be non-NULL.
    ///
    /// Parameter `runLoop`: A reference to a run loop from which the target
    /// should be unscheduled.  Must be non-NULL.
    ///
    /// Parameter `runLoopMode`: The mode on which to unschedule the target.
    /// Must be non-NULL.
    ///
    /// Returns: Returns TRUE if the target is unscheduled successfully;
    /// FALSE otherwise.
    #[doc(alias = "SCNetworkReachabilityUnscheduleFromRunLoop")]
    #[deprecated]
    #[inline]
    pub fn unschedule_from_run_loop(&self, run_loop: &CFRunLoop, run_loop_mode: &CFString) -> bool {
        extern "C-unwind" {
            fn SCNetworkReachabilityUnscheduleFromRunLoop(
                target: &SCNetworkReachability,
                run_loop: &CFRunLoop,
                run_loop_mode: &CFString,
            ) -> Boolean;
        }
        let ret =
            unsafe { SCNetworkReachabilityUnscheduleFromRunLoop(self, run_loop, run_loop_mode) };
        ret != 0
    }

    /// Schedule or unschedule callbacks for the given target on the given
    /// dispatch queue.
    ///
    /// Parameter `target`: The address or name that is set up for asynchronous
    /// notifications.  Must be non-NULL.
    ///
    /// Parameter `queue`: A libdispatch queue to run the callback on.
    /// Pass NULL to unschedule callbacks.
    ///
    /// Returns: Returns TRUE if the target is scheduled or unscheduled successfully;
    /// FALSE otherwise.
    ///
    /// # Safety
    ///
    /// `queue` possibly has additional threading requirements.
    #[doc(alias = "SCNetworkReachabilitySetDispatchQueue")]
    #[cfg(feature = "dispatch2")]
    #[deprecated]
    #[inline]
    pub unsafe fn set_dispatch_queue(&self, queue: Option<&DispatchQueue>) -> bool {
        extern "C-unwind" {
            fn SCNetworkReachabilitySetDispatchQueue(
                target: &SCNetworkReachability,
                queue: Option<&DispatchQueue>,
            ) -> Boolean;
        }
        let ret = unsafe { SCNetworkReachabilitySetDispatchQueue(self, queue) };
        ret != 0
    }
}

#[cfg(feature = "libc")]
#[deprecated = "renamed to `SCNetworkReachability::with_address`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilityCreateWithAddress(
    allocator: Option<&CFAllocator>,
    address: NonNull<libc::sockaddr>,
) -> Option<CFRetained<SCNetworkReachability>> {
    extern "C-unwind" {
        fn SCNetworkReachabilityCreateWithAddress(
            allocator: Option<&CFAllocator>,
            address: NonNull<libc::sockaddr>,
        ) -> Option<NonNull<SCNetworkReachability>>;
    }
    let ret = unsafe { SCNetworkReachabilityCreateWithAddress(allocator, address) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[cfg(feature = "libc")]
#[deprecated = "renamed to `SCNetworkReachability::with_address_pair`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilityCreateWithAddressPair(
    allocator: Option<&CFAllocator>,
    local_address: *const libc::sockaddr,
    remote_address: *const libc::sockaddr,
) -> Option<CFRetained<SCNetworkReachability>> {
    extern "C-unwind" {
        fn SCNetworkReachabilityCreateWithAddressPair(
            allocator: Option<&CFAllocator>,
            local_address: *const libc::sockaddr,
            remote_address: *const libc::sockaddr,
        ) -> Option<NonNull<SCNetworkReachability>>;
    }
    let ret = unsafe {
        SCNetworkReachabilityCreateWithAddressPair(allocator, local_address, remote_address)
    };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `SCNetworkReachability::with_name`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilityCreateWithName(
    allocator: Option<&CFAllocator>,
    nodename: NonNull<c_char>,
) -> Option<CFRetained<SCNetworkReachability>> {
    extern "C-unwind" {
        fn SCNetworkReachabilityCreateWithName(
            allocator: Option<&CFAllocator>,
            nodename: NonNull<c_char>,
        ) -> Option<NonNull<SCNetworkReachability>>;
    }
    let ret = unsafe { SCNetworkReachabilityCreateWithName(allocator, nodename) };
    ret.map(|ret| unsafe { CFRetained::from_raw(ret) })
}

#[deprecated = "renamed to `SCNetworkReachability::flags`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilityGetFlags(
    target: &SCNetworkReachability,
    flags: NonNull<SCNetworkReachabilityFlags>,
) -> bool {
    extern "C-unwind" {
        fn SCNetworkReachabilityGetFlags(
            target: &SCNetworkReachability,
            flags: NonNull<SCNetworkReachabilityFlags>,
        ) -> Boolean;
    }
    let ret = unsafe { SCNetworkReachabilityGetFlags(target, flags) };
    ret != 0
}

#[deprecated = "renamed to `SCNetworkReachability::set_callback`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilitySetCallback(
    target: &SCNetworkReachability,
    callout: SCNetworkReachabilityCallBack,
    context: *mut SCNetworkReachabilityContext,
) -> bool {
    extern "C-unwind" {
        fn SCNetworkReachabilitySetCallback(
            target: &SCNetworkReachability,
            callout: SCNetworkReachabilityCallBack,
            context: *mut SCNetworkReachabilityContext,
        ) -> Boolean;
    }
    let ret = unsafe { SCNetworkReachabilitySetCallback(target, callout, context) };
    ret != 0
}

#[deprecated = "renamed to `SCNetworkReachability::schedule_with_run_loop`"]
#[inline]
pub extern "C-unwind" fn SCNetworkReachabilityScheduleWithRunLoop(
    target: &SCNetworkReachability,
    run_loop: &CFRunLoop,
    run_loop_mode: &CFString,
) -> bool {
    extern "C-unwind" {
        fn SCNetworkReachabilityScheduleWithRunLoop(
            target: &SCNetworkReachability,
            run_loop: &CFRunLoop,
            run_loop_mode: &CFString,
        ) -> Boolean;
    }
    let ret = unsafe { SCNetworkReachabilityScheduleWithRunLoop(target, run_loop, run_loop_mode) };
    ret != 0
}

#[deprecated = "renamed to `SCNetworkReachability::unschedule_from_run_loop`"]
#[inline]
pub extern "C-unwind" fn SCNetworkReachabilityUnscheduleFromRunLoop(
    target: &SCNetworkReachability,
    run_loop: &CFRunLoop,
    run_loop_mode: &CFString,
) -> bool {
    extern "C-unwind" {
        fn SCNetworkReachabilityUnscheduleFromRunLoop(
            target: &SCNetworkReachability,
            run_loop: &CFRunLoop,
            run_loop_mode: &CFString,
        ) -> Boolean;
    }
    let ret =
        unsafe { SCNetworkReachabilityUnscheduleFromRunLoop(target, run_loop, run_loop_mode) };
    ret != 0
}

#[cfg(feature = "dispatch2")]
#[deprecated = "renamed to `SCNetworkReachability::set_dispatch_queue`"]
#[inline]
pub unsafe extern "C-unwind" fn SCNetworkReachabilitySetDispatchQueue(
    target: &SCNetworkReachability,
    queue: Option<&DispatchQueue>,
) -> bool {
    extern "C-unwind" {
        fn SCNetworkReachabilitySetDispatchQueue(
            target: &SCNetworkReachability,
            queue: Option<&DispatchQueue>,
        ) -> Boolean;
    }
    let ret = unsafe { SCNetworkReachabilitySetDispatchQueue(target, queue) };
    ret != 0
}
