//! 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::*;
use objc2_foundation::*;

use crate::*;

/// Characteristic properties determine how the characteristic value can be    used, or how the descriptor(s) can be accessed. Can be combined. Unless
/// otherwise specified, properties are valid for local characteristics published via
///
/// ```text
///  CBPeripheralManager
/// ```
///
/// .
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcharacteristicproperties?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CBCharacteristicProperties(pub NSUInteger);
bitflags::bitflags! {
    impl CBCharacteristicProperties: NSUInteger {
        #[doc(alias = "CBCharacteristicPropertyBroadcast")]
        const Broadcast = 0x01;
        #[doc(alias = "CBCharacteristicPropertyRead")]
        const Read = 0x02;
        #[doc(alias = "CBCharacteristicPropertyWriteWithoutResponse")]
        const WriteWithoutResponse = 0x04;
        #[doc(alias = "CBCharacteristicPropertyWrite")]
        const Write = 0x08;
        #[doc(alias = "CBCharacteristicPropertyNotify")]
        const Notify = 0x10;
        #[doc(alias = "CBCharacteristicPropertyIndicate")]
        const Indicate = 0x20;
        #[doc(alias = "CBCharacteristicPropertyAuthenticatedSignedWrites")]
        const AuthenticatedSignedWrites = 0x40;
        #[doc(alias = "CBCharacteristicPropertyExtendedProperties")]
        const ExtendedProperties = 0x80;
        #[doc(alias = "CBCharacteristicPropertyNotifyEncryptionRequired")]
        const NotifyEncryptionRequired = 0x100;
        #[doc(alias = "CBCharacteristicPropertyIndicateEncryptionRequired")]
        const IndicateEncryptionRequired = 0x200;
    }
}

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

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

extern_class!(
    /// Represents a service's characteristic.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbcharacteristic?language=objc)
    #[unsafe(super(CBAttribute, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "CBAttribute")]
    pub struct CBCharacteristic;
);

#[cfg(feature = "CBAttribute")]
unsafe impl NSObjectProtocol for CBCharacteristic {}

#[cfg(feature = "CBAttribute")]
impl CBCharacteristic {
    extern_methods!(
        #[cfg(feature = "CBService")]
        /// A back-pointer to the service this characteristic belongs to.
        #[unsafe(method(service))]
        #[unsafe(method_family = none)]
        pub unsafe fn service(&self) -> Option<Retained<CBService>>;

        /// The properties of the characteristic.
        #[unsafe(method(properties))]
        #[unsafe(method_family = none)]
        pub unsafe fn properties(&self) -> CBCharacteristicProperties;

        /// The value of the characteristic.
        #[unsafe(method(value))]
        #[unsafe(method_family = none)]
        pub unsafe fn value(&self) -> Option<Retained<NSData>>;

        #[cfg(feature = "CBDescriptor")]
        /// A list of the CBDescriptors that have so far been discovered in this characteristic.
        #[unsafe(method(descriptors))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptors(&self) -> Option<Retained<NSArray<CBDescriptor>>>;

        /// Whether the characteristic is currently broadcasted or not.
        #[deprecated]
        #[unsafe(method(isBroadcasted))]
        #[unsafe(method_family = none)]
        pub unsafe fn isBroadcasted(&self) -> bool;

        /// Whether the characteristic is currently notifying or not.
        #[unsafe(method(isNotifying))]
        #[unsafe(method_family = none)]
        pub unsafe fn isNotifying(&self) -> bool;
    );
}

/// Methods declared on superclass `CBAttribute`.
#[cfg(feature = "CBAttribute")]
impl CBCharacteristic {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

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

/// Read, write, and encryption permissions for an ATT attribute. Can be combined.
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbattributepermissions?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CBAttributePermissions(pub NSUInteger);
bitflags::bitflags! {
    impl CBAttributePermissions: NSUInteger {
        #[doc(alias = "CBAttributePermissionsReadable")]
        const Readable = 0x01;
        #[doc(alias = "CBAttributePermissionsWriteable")]
        const Writeable = 0x02;
        #[doc(alias = "CBAttributePermissionsReadEncryptionRequired")]
        const ReadEncryptionRequired = 0x04;
        #[doc(alias = "CBAttributePermissionsWriteEncryptionRequired")]
        const WriteEncryptionRequired = 0x08;
    }
}

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

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

extern_class!(
    /// Used to create a local characteristic, which can be added to the local database via
    /// <code>
    /// CBPeripheralManager
    /// </code>
    /// . Once a characteristic
    /// is published, it is cached and can no longer be changed.
    /// If a characteristic value is specified, it will be cached and marked
    /// <code>
    /// CBCharacteristicPropertyRead
    /// </code>
    /// and
    /// <code>
    /// CBAttributePermissionsReadable
    /// </code>
    /// . If a characteristic value needs to be writeable, or may change during the lifetime of the
    /// published
    /// <code>
    /// CBService
    /// </code>
    /// , it is considered a dynamic value and will be requested on-demand. Dynamic values are identified by a
    /// <i>
    /// value
    /// </i>
    /// of
    /// <i>
    /// nil
    /// </i>
    /// .
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/corebluetooth/cbmutablecharacteristic?language=objc)
    #[unsafe(super(CBCharacteristic, CBAttribute, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "CBAttribute")]
    pub struct CBMutableCharacteristic;
);

#[cfg(feature = "CBAttribute")]
unsafe impl NSObjectProtocol for CBMutableCharacteristic {}

#[cfg(feature = "CBAttribute")]
impl CBMutableCharacteristic {
    extern_methods!(
        /// The permissions of the characteristic value.
        ///
        ///
        /// See: CBAttributePermissions
        #[unsafe(method(permissions))]
        #[unsafe(method_family = none)]
        pub unsafe fn permissions(&self) -> CBAttributePermissions;

        /// Setter for [`permissions`][Self::permissions].
        #[unsafe(method(setPermissions:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPermissions(&self, permissions: CBAttributePermissions);

        #[cfg(all(feature = "CBCentral", feature = "CBPeer"))]
        /// For notifying characteristics, the set of currently subscribed centrals.
        #[unsafe(method(subscribedCentrals))]
        #[unsafe(method_family = none)]
        pub unsafe fn subscribedCentrals(&self) -> Option<Retained<NSArray<CBCentral>>>;

        #[unsafe(method(properties))]
        #[unsafe(method_family = none)]
        pub unsafe fn properties(&self) -> CBCharacteristicProperties;

        /// Setter for [`properties`][Self::properties].
        #[unsafe(method(setProperties:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setProperties(&self, properties: CBCharacteristicProperties);

        #[unsafe(method(value))]
        #[unsafe(method_family = none)]
        pub unsafe fn value(&self) -> Option<Retained<NSData>>;

        /// Setter for [`value`][Self::value].
        #[unsafe(method(setValue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setValue(&self, value: Option<&NSData>);

        #[cfg(feature = "CBDescriptor")]
        #[unsafe(method(descriptors))]
        #[unsafe(method_family = none)]
        pub unsafe fn descriptors(&self) -> Option<Retained<NSArray<CBDescriptor>>>;

        #[cfg(feature = "CBDescriptor")]
        /// Setter for [`descriptors`][Self::descriptors].
        #[unsafe(method(setDescriptors:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDescriptors(&self, descriptors: Option<&NSArray<CBDescriptor>>);

        #[cfg(feature = "CBUUID")]
        /// Parameter `UUID`: The Bluetooth UUID of the characteristic.
        ///
        /// Parameter `properties`: The properties of the characteristic.
        ///
        /// Parameter `value`: The characteristic value to be cached. If
        /// <i>
        /// nil
        /// </i>
        /// , the value will be dynamic and requested on-demand.
        ///
        /// Parameter `permissions`: The permissions of the characteristic value.
        ///
        ///
        /// Returns an initialized characteristic.
        #[unsafe(method(initWithType:properties:value:permissions:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithType_properties_value_permissions(
            this: Allocated<Self>,
            uuid: &CBUUID,
            properties: CBCharacteristicProperties,
            value: Option<&NSData>,
            permissions: CBAttributePermissions,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `CBAttribute`.
#[cfg(feature = "CBAttribute")]
impl CBMutableCharacteristic {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;
    );
}

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