//! This file has been automatically generated by `objc2`'s `header-translator`.
//! DO NOT EDIT
use core::ffi::*;
use core::ptr::NonNull;
use objc2::__framework_prelude::*;
#[cfg(feature = "objc2-core-foundation")]
use objc2_core_foundation::*;
use objc2_foundation::*;

use crate::*;

/// Represents the current state of a CBCentralManager.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerstate?language=objc)
// NS_ENUM
#[deprecated = "Use CBManagerState instead"]
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CBCentralManagerState(pub NSInteger);
impl CBCentralManagerState {
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStateUnknown")]
    pub const Unknown: Self = Self(CBManagerState::Unknown.0);
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStateResetting")]
    pub const Resetting: Self = Self(CBManagerState::Resetting.0);
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStateUnsupported")]
    pub const Unsupported: Self = Self(CBManagerState::Unsupported.0);
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStateUnauthorized")]
    pub const Unauthorized: Self = Self(CBManagerState::Unauthorized.0);
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStatePoweredOff")]
    pub const PoweredOff: Self = Self(CBManagerState::PoweredOff.0);
    #[cfg(feature = "CBManager")]
    #[deprecated = "Use CBManagerState instead"]
    #[doc(alias = "CBCentralManagerStatePoweredOn")]
    pub const PoweredOn: Self = Self(CBManagerState::PoweredOn.0);
}

unsafe impl Encode for CBCentralManagerState {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for CBCentralManagerState {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// Represents the connection state of a peer.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbconnectionevent?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CBConnectionEvent(pub NSInteger);
impl CBConnectionEvent {
    #[doc(alias = "CBConnectionEventPeerDisconnected")]
    pub const PeerDisconnected: Self = Self(0);
    #[doc(alias = "CBConnectionEventPeerConnected")]
    pub const PeerConnected: Self = Self(1);
}

unsafe impl Encode for CBConnectionEvent {
    const ENCODING: Encoding = NSInteger::ENCODING;
}

unsafe impl RefEncode for CBConnectionEvent {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

/// The set of device specific features.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerfeature?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CBCentralManagerFeature(pub NSUInteger);
bitflags::bitflags! {
    impl CBCentralManagerFeature: NSUInteger {
        #[doc(alias = "CBCentralManagerFeatureExtendedScanAndConnect")]
        const ExtendedScanAndConnect = 1<<0;
    }
}

unsafe impl Encode for CBCentralManagerFeature {
    const ENCODING: Encoding = NSUInteger::ENCODING;
}

unsafe impl RefEncode for CBCentralManagerFeature {
    const ENCODING_REF: Encoding = Encoding::Pointer(&Self::ENCODING);
}

extern_class!(
    /// Entry point to the central role. Commands should only be issued when its state is
    /// <code>
    /// CBCentralManagerStatePoweredOn
    /// </code>
    /// .
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcentralmanager?language=objc)
    #[unsafe(super(CBManager, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "CBManager")]
    pub struct CBCentralManager;
);

#[cfg(feature = "CBManager")]
unsafe impl NSObjectProtocol for CBCentralManager {}

#[cfg(feature = "CBManager")]
impl CBCentralManager {
    extern_methods!(
        /// The delegate object that will receive central events.
        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub unsafe fn delegate(
            &self,
        ) -> Option<Retained<ProtocolObject<dyn CBCentralManagerDelegate>>>;

        /// This is a [weak property][objc2::topics::weak_property].
        /// Setter for [`delegate`][Self::delegate].
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate(
            &self,
            delegate: Option<&ProtocolObject<dyn CBCentralManagerDelegate>>,
        );

        /// Whether or not the central is currently scanning.
        #[unsafe(method(isScanning))]
        #[unsafe(method_family = none)]
        pub unsafe fn isScanning(&self) -> bool;

        /// Parameter `features`: One or more features you would like to check if supported.
        ///
        ///
        /// Returns a boolean value representing the support for the provided features.
        #[unsafe(method(supportsFeatures:))]
        #[unsafe(method_family = none)]
        pub unsafe fn supportsFeatures(features: CBCentralManagerFeature) -> bool;

        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[cfg(all(feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `identifiers`: A list of
        /// <code>
        /// NSUUID
        /// </code>
        /// objects.
        ///
        ///
        /// Attempts to retrieve the
        /// <code>
        /// CBPeripheral
        /// </code>
        /// object(s) with the corresponding
        /// <i>
        /// identifiers
        /// </i>
        /// .
        ///
        ///
        /// Returns: A list of
        /// <code>
        /// CBPeripheral
        /// </code>
        /// objects.
        #[unsafe(method(retrievePeripheralsWithIdentifiers:))]
        #[unsafe(method_family = none)]
        pub unsafe fn retrievePeripheralsWithIdentifiers(
            &self,
            identifiers: &NSArray<NSUUID>,
        ) -> Retained<NSArray<CBPeripheral>>;

        #[cfg(all(feature = "CBPeer", feature = "CBPeripheral", feature = "CBUUID"))]
        /// Retrieves all peripherals that are connected to the system and implement any of the services listed in
        /// <i>
        /// serviceUUIDs
        /// </i>
        /// .
        /// Note that this set can include peripherals which were connected by other applications, which will need to be connected locally
        /// via {
        ///
        /// ```text
        ///  connectPeripheral:options:} before they can be used.
        ///
        ///     @return        A list of <code>CBPeripheral</code> objects.
        ///
        ///  
        ///
        /// ```
        #[unsafe(method(retrieveConnectedPeripheralsWithServices:))]
        #[unsafe(method_family = none)]
        pub unsafe fn retrieveConnectedPeripheralsWithServices(
            &self,
            service_uui_ds: &NSArray<CBUUID>,
        ) -> Retained<NSArray<CBPeripheral>>;

        #[cfg(feature = "CBUUID")]
        /// Parameter `serviceUUIDs`: A list of
        /// <code>
        /// CBUUID
        /// </code>
        /// objects representing the service(s) to scan for.
        ///
        /// Parameter `options`: An optional dictionary specifying options for the scan.
        ///
        ///
        /// Starts scanning for peripherals that are advertising any of the services listed in
        /// <i>
        /// serviceUUIDs
        /// </i>
        /// . Although strongly discouraged,
        /// if
        /// <i>
        /// serviceUUIDs
        /// </i>
        /// is
        /// <i>
        /// nil
        /// </i>
        /// all discovered peripherals will be returned. If the central is already scanning with different
        /// <i>
        /// serviceUUIDs
        /// </i>
        /// or
        /// <i>
        /// options
        /// </i>
        /// , the provided parameters will replace them.
        /// Applications that have specified the
        /// <code>
        /// bluetooth-central
        /// </code>
        /// background mode are allowed to scan while backgrounded, with two
        /// caveats: the scan must specify one or more service types in
        /// <i>
        /// serviceUUIDs
        /// </i>
        /// , and the
        /// <code>
        /// CBCentralManagerScanOptionAllowDuplicatesKey
        /// </code>
        /// scan option will be ignored.
        ///
        ///
        /// See: centralManager:didDiscoverPeripheral:advertisementData:RSSI:
        ///
        /// See also: CBCentralManagerScanOptionAllowDuplicatesKey
        ///
        /// See also: CBCentralManagerScanOptionSolicitedServiceUUIDsKey
        #[unsafe(method(scanForPeripheralsWithServices:options:))]
        #[unsafe(method_family = none)]
        pub unsafe fn scanForPeripheralsWithServices_options(
            &self,
            service_uui_ds: Option<&NSArray<CBUUID>>,
            options: Option<&NSDictionary<NSString, AnyObject>>,
        );

        /// Stops scanning for peripherals.
        #[unsafe(method(stopScan))]
        #[unsafe(method_family = none)]
        pub unsafe fn stopScan(&self);

        #[cfg(all(feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// to be connected.
        ///
        /// Parameter `options`: An optional dictionary specifying connection behavior options.
        ///
        ///
        /// Initiates a connection to
        /// <i>
        /// peripheral
        /// </i>
        /// . Connection attempts never time out and, depending on the outcome, will result
        /// in a call to either {
        ///
        /// ```text
        ///  centralManager:didConnectPeripheral:} or {@link centralManager:didFailToConnectPeripheral:error:}.
        ///                       Pending attempts are cancelled automatically upon deallocation of <i>peripheral</i>, and explicitly via {@link cancelPeripheralConnection}.
        ///
        ///   @see                centralManager:didConnectPeripheral:
        ///   @see                centralManager:didFailToConnectPeripheral:error:
        ///   @seealso            CBConnectPeripheralOptionNotifyOnConnectionKey
        ///   @seealso            CBConnectPeripheralOptionNotifyOnDisconnectionKey
        ///   @seealso            CBConnectPeripheralOptionNotifyOnNotificationKey
        ///   @seealso            CBConnectPeripheralOptionEnableTransportBridgingKey
        ///     @seealso            CBConnectPeripheralOptionRequiresANCS
        ///   @seealso            CBConnectPeripheralOptionEnableAutoReconnect
        ///
        ///  
        ///
        /// ```
        #[unsafe(method(connectPeripheral:options:))]
        #[unsafe(method_family = none)]
        pub unsafe fn connectPeripheral_options(
            &self,
            peripheral: &CBPeripheral,
            options: Option<&NSDictionary<NSString, AnyObject>>,
        );

        #[cfg(all(feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `peripheral`: A
        /// <code>
        /// CBPeripheral
        /// </code>
        /// .
        ///
        ///
        /// Cancels an active or pending connection to
        /// <i>
        /// peripheral
        /// </i>
        /// . Note that this is non-blocking, and any
        /// <code>
        /// CBPeripheral
        /// </code>
        /// commands that are still pending to
        /// <i>
        /// peripheral
        /// </i>
        /// may or may not complete.
        ///
        ///
        /// See: centralManager:didDisconnectPeripheral:error:
        #[unsafe(method(cancelPeripheralConnection:))]
        #[unsafe(method_family = none)]
        pub unsafe fn cancelPeripheralConnection(&self, peripheral: &CBPeripheral);

        #[cfg(feature = "CBCentralManagerConstants")]
        /// Parameter `options`: A dictionary specifying connection event options.
        ///
        ///
        /// Calls {
        ///
        /// ```text
        ///  centralManager:connectionEventDidOccur:forPeripheral:} when a connection event occurs matching any of the given options.
        ///                       Passing nil in the option parameter clears any prior registered matching options.
        ///
        ///   @see                centralManager:connectionEventDidOccur:forPeripheral:
        ///   @seealso            CBConnectionEventMatchingOptionServiceUUIDs
        ///   @seealso            CBConnectionEventMatchingOptionPeripheralUUIDs
        ///  
        ///
        /// ```
        #[unsafe(method(registerForConnectionEventsWithOptions:))]
        #[unsafe(method_family = none)]
        pub unsafe fn registerForConnectionEventsWithOptions(
            &self,
            options: Option<&NSDictionary<CBConnectionEventMatchingOption, AnyObject>>,
        );
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "CBManager")]
impl CBCentralManager {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

extern_protocol!(
    /// The delegate of a {
    ///
    /// ```text
    ///  CBCentralManager} object must adopt the <code>CBCentralManagerDelegate</code> protocol. The
    ///               single required method indicates the availability of the central manager, while the optional methods allow for the discovery and
    ///               connection of peripherals.
    ///
    ///  
    ///
    /// ```
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcentralmanagerdelegate?language=objc)
    pub unsafe trait CBCentralManagerDelegate: NSObjectProtocol {
        #[cfg(feature = "CBManager")]
        /// Parameter `central`: The central manager whose state has changed.
        ///
        ///
        /// Invoked whenever the central manager's state has been updated. Commands should only be issued when the state is
        /// <code>
        /// CBCentralManagerStatePoweredOn
        /// </code>
        /// . A state below
        /// <code>
        /// CBCentralManagerStatePoweredOn
        /// </code>
        /// implies that scanning has stopped and any connected peripherals have been disconnected. If the state moves below
        /// <code>
        /// CBCentralManagerStatePoweredOff
        /// </code>
        /// , all
        /// <code>
        /// CBPeripheral
        /// </code>
        /// objects obtained from this central
        /// manager become invalid and must be retrieved or discovered again.
        ///
        ///
        /// See: state
        #[unsafe(method(centralManagerDidUpdateState:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManagerDidUpdateState(&self, central: &CBCentralManager);

        #[cfg(feature = "CBManager")]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `dict`: A dictionary containing information about
        /// <i>
        /// central
        /// </i>
        /// that was preserved by the system at the time the app was terminated.
        ///
        ///
        /// For apps that opt-in to state preservation and restoration, this is the first method invoked when your app is relaunched into
        /// the background to complete some Bluetooth-related task. Use this method to synchronize your app's state with the state of the
        /// Bluetooth system.
        ///
        ///
        /// See also: CBCentralManagerRestoredStatePeripheralsKey;
        ///
        /// See also: CBCentralManagerRestoredStateScanServicesKey;
        ///
        /// See also: CBCentralManagerRestoredStateScanOptionsKey;
        #[optional]
        #[unsafe(method(centralManager:willRestoreState:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_willRestoreState(
            &self,
            central: &CBCentralManager,
            dict: &NSDictionary<NSString, AnyObject>,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this update.
        ///
        /// Parameter `peripheral`: A
        /// <code>
        /// CBPeripheral
        /// </code>
        /// object.
        ///
        /// Parameter `advertisementData`: A dictionary containing any advertisement and scan response data.
        ///
        /// Parameter `RSSI`: The current RSSI of
        /// <i>
        /// peripheral
        /// </i>
        /// , in dBm. A value of
        /// <code>
        /// 127
        /// </code>
        /// is reserved and indicates the RSSI
        /// was not available.
        ///
        ///
        /// This method is invoked while scanning, upon the discovery of
        /// <i>
        /// peripheral
        /// </i>
        /// by
        /// <i>
        /// central
        /// </i>
        /// . A discovered peripheral must
        /// be retained in order to use it; otherwise, it is assumed to not be of interest and will be cleaned up by the central manager. For
        /// a list of
        /// <i>
        /// advertisementData
        /// </i>
        /// keys, see {
        ///
        /// ```text
        ///  CBAdvertisementDataLocalNameKey} and other similar constants.
        ///
        ///   @seealso                    CBAdvertisementData.h
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didDiscoverPeripheral:advertisementData:RSSI:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didDiscoverPeripheral_advertisementData_RSSI(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
            advertisement_data: &NSDictionary<NSString, AnyObject>,
            rssi: &NSNumber,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that has connected.
        ///
        ///
        /// This method is invoked when a connection initiated by {
        ///
        /// ```text
        ///  connectPeripheral:options:} has succeeded.
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didConnectPeripheral:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didConnectPeripheral(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that has failed to connect.
        ///
        /// Parameter `error`: The cause of the failure.
        ///
        ///
        /// This method is invoked when a connection initiated by {
        ///
        /// ```text
        ///  connectPeripheral:options:} has failed to complete. As connection attempts do not
        ///                       timeout, the failure of a connection is atypical and usually indicative of a transient issue.
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didFailToConnectPeripheral:error:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didFailToConnectPeripheral_error(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
            error: Option<&NSError>,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that has disconnected.
        ///
        /// Parameter `error`: If an error occurred, the cause of the failure.
        ///
        ///
        /// This method is invoked upon the disconnection of a peripheral that was connected by {
        ///
        /// ```text
        ///  connectPeripheral:options:}. If the disconnection
        ///                       was not initiated by {@link cancelPeripheralConnection}, the cause will be detailed in the <i>error</i> parameter. Once this method has been
        ///                       called, no more methods will be invoked on <i>peripheral</i>'s <code>CBPeripheralDelegate</code>.
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didDisconnectPeripheral:error:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didDisconnectPeripheral_error(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
            error: Option<&NSError>,
        );

        #[cfg(all(
            feature = "CBManager",
            feature = "CBPeer",
            feature = "CBPeripheral",
            feature = "objc2-core-foundation"
        ))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that has disconnected.
        ///
        /// Parameter `timestamp`: Timestamp of the disconnection, it can be now or a few seconds ago.
        ///
        /// Parameter `isReconnecting`: If reconnect was triggered upon disconnection.
        ///
        /// Parameter `error`: If an error occurred, the cause of the failure.
        ///
        ///
        /// This method is invoked upon the disconnection of a peripheral that was connected by {
        ///
        /// ```text
        ///  connectPeripheral:options:}. If perihperal is
        ///                       connected with connect option {@link CBConnectPeripheralOptionEnableAutoReconnect}, once this method has been called, the system
        ///                       will automatically invoke connect to the peripheral. And if connection is established with the peripheral afterwards,
        ///                       {@link centralManager:didConnectPeripheral:} can be invoked. If perihperal is connected without option
        ///                       CBConnectPeripheralOptionEnableAutoReconnect, once this method has been called, no more methods will be invoked on
        ///                        <i>peripheral</i>'s <code>CBPeripheralDelegate</code> .
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didDisconnectPeripheral:timestamp:isReconnecting:error:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didDisconnectPeripheral_timestamp_isReconnecting_error(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
            timestamp: CFAbsoluteTime,
            is_reconnecting: bool,
            error: Option<&NSError>,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `event`: The
        /// <code>
        /// CBConnectionEvent
        /// </code>
        /// that has occurred.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that caused the event.
        ///
        ///
        /// This method is invoked upon the connection or disconnection of a peripheral that matches any of the options provided in {
        ///
        /// ```text
        ///  registerForConnectionEventsWithOptions:}.
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:connectionEventDidOccur:forPeripheral:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_connectionEventDidOccur_forPeripheral(
            &self,
            central: &CBCentralManager,
            event: CBConnectionEvent,
            peripheral: &CBPeripheral,
        );

        #[cfg(all(feature = "CBManager", feature = "CBPeer", feature = "CBPeripheral"))]
        /// Parameter `central`: The central manager providing this information.
        ///
        /// Parameter `peripheral`: The
        /// <code>
        /// CBPeripheral
        /// </code>
        /// that caused the event.
        ///
        ///
        /// This method is invoked when the authorization status changes for a peripheral connected with {
        ///
        /// ```text
        ///  connectPeripheral:} option {@link CBConnectPeripheralOptionRequiresANCS}.
        ///
        ///  
        ///
        /// ```
        #[optional]
        #[unsafe(method(centralManager:didUpdateANCSAuthorizationForPeripheral:))]
        #[unsafe(method_family = none)]
        unsafe fn centralManager_didUpdateANCSAuthorizationForPeripheral(
            &self,
            central: &CBCentralManager,
            peripheral: &CBPeripheral,
        );
    }
);
