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

/// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordzonecapabilities?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKRecordZoneCapabilities(pub NSUInteger);
bitflags::bitflags! {
    impl CKRecordZoneCapabilities: NSUInteger {
/// This zone supports `CKFetchRecordZoneChangesOperation`
        #[doc(alias = "CKRecordZoneCapabilityFetchChanges")]
        const FetchChanges = 1<<0;
/// Batched changes to this zone happen atomically
        #[doc(alias = "CKRecordZoneCapabilityAtomic")]
        const Atomic = 1<<1;
/// Records in this zone can be shared
        #[doc(alias = "CKRecordZoneCapabilitySharing")]
        const Sharing = 1<<2;
/// This zone supports a single `CKShare` record that shares all records in the zone
        #[doc(alias = "CKRecordZoneCapabilityZoneWideSharing")]
        const ZoneWideSharing = 1<<3;
    }
}

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordzoneencryptionscope?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKRecordZoneEncryptionScope(pub NSInteger);
impl CKRecordZoneEncryptionScope {
    /// Zone uses per-record encryption keys for any encrypted values on a record or share.
    ///
    /// This is the default encryption scope for a record zone.
    #[doc(alias = "CKRecordZoneEncryptionScopePerRecord")]
    pub const PerRecord: Self = Self(0);
    /// Zone uses per-zone encryption keys for encrypted values across all records and the zone-wide share, if present.
    ///
    /// This is an optional optimization that can reduce the overall storage used by encryption keys in a zone.
    /// Note that:
    /// - Record zones using per-zone encryption only support zone-wide sharing.
    /// - Encryption scope can only be assigned at zone creation and cannot be changed for the lifetime of the zone.
    /// - The server will not return zones using per-zone encryption to device OS versions older than the corresponding API availability version.
    /// - An older OS trying to overwrite an existing zone using per-zone encryption due to a naming collision will result in a `.serverRejectedRequest` error.
    /// - On device OS upgrade, your application is responsible for fetching database changes via `CKFetchDatabaseChangesOperation` with a nil sync token to ensure it has
    /// received all the zones available to it from the server.
    #[doc(alias = "CKRecordZoneEncryptionScopePerZone")]
    pub const PerZone: Self = Self(1);
}

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

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

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordzonedefaultname?language=objc)
    pub static CKRecordZoneDefaultName: &'static NSString;
}

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordzone?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKRecordZone;
);

extern_conformance!(
    unsafe impl NSCoding for CKRecordZone {}
);

extern_conformance!(
    unsafe impl NSCopying for CKRecordZone {}
);

unsafe impl CopyingHelper for CKRecordZone {
    type Result = Self;
}

extern_conformance!(
    unsafe impl NSObjectProtocol for CKRecordZone {}
);

extern_conformance!(
    unsafe impl NSSecureCoding for CKRecordZone {}
);

impl CKRecordZone {
    extern_methods!(
        #[unsafe(method(defaultRecordZone))]
        #[unsafe(method_family = none)]
        pub unsafe fn defaultRecordZone() -> Retained<CKRecordZone>;

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

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

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

        #[cfg(feature = "CKRecordZoneID")]
        #[unsafe(method(initWithZoneID:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithZoneID(
            this: Allocated<Self>,
            zone_id: &CKRecordZoneID,
        ) -> Retained<Self>;

        #[cfg(feature = "CKRecordZoneID")]
        #[unsafe(method(zoneID))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneID(&self) -> Retained<CKRecordZoneID>;

        /// Capabilities on locally-created record zones are not valid until the record zone is saved. Capabilities on record zones fetched from the server are valid.
        #[unsafe(method(capabilities))]
        #[unsafe(method_family = none)]
        pub unsafe fn capabilities(&self) -> CKRecordZoneCapabilities;

        #[cfg(feature = "CKReference")]
        /// The share property on a record zone will only be set on zones fetched from the server and only if a
        /// corresponding zone-wide share record for the zone exists on the server.
        ///
        /// You can create a zone-wide share for a zone using `-[CKShare initWithRecordZoneID:]`.
        ///
        /// Zone-wide sharing is only supported in zones with the `CKRecordZoneCapabilityZoneWideSharing` sharing capability.
        /// You cannot share a zone if it already contains shared records.
        #[unsafe(method(share))]
        #[unsafe(method_family = none)]
        pub unsafe fn share(&self) -> Option<Retained<CKReference>>;

        /// The encryption scope determines the granularity at which encryption keys are stored within the zone.
        ///
        /// Zone encryption scope defaults to `CKRecordZoneEncryptionScopePerRecord` and can only be modified before zone creation. Attempting to change the encryption
        /// scope of an existing zone is invalid and will result in an error.
        ///
        /// Zones using `CKRecordZoneEncryptionScopePerZone` can only use zone-wide sharing and are not compatible with older device OS versions. Refer to `CKRecordZoneEncryptionScope` for more info.
        #[unsafe(method(encryptionScope))]
        #[unsafe(method_family = none)]
        pub unsafe fn encryptionScope(&self) -> CKRecordZoneEncryptionScope;

        /// Setter for [`encryptionScope`][Self::encryptionScope].
        #[unsafe(method(setEncryptionScope:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setEncryptionScope(&self, encryption_scope: CKRecordZoneEncryptionScope);
    );
}
