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

/// Locally edited keys are sent to the server, updating the record if the server record has not been modified. This is the default and recommended save policy for regular use.
/// This policy compares the record change tag with the server record, and may return
/// `CKErrorServerRecordChanged`if the server record has been modified, for example by another device.
/// Note: A
/// `CKShare`record is always treated as
/// `CKRecordSaveIfServerRecordUnchanged,`regardless of the
/// `savePolicy`of the operation that modifies the share.
///
///
///
/// Locally edited keys are written to the server, updating the record even if the server record has been modified.
/// Note: This policy should be used with care, as it can overwrite changes made by other devices.
/// Any previously committed change to the server, for example by other devices, will always be overwritten by the locally changed value.
/// Note: A
/// `CKShare`record is always treated as
/// `CKRecordSaveIfServerRecordUnchanged,`regardless of the
/// `savePolicy`of the operation that modifies the share.
/// For non-CKShare records, this policy does not compare the record change tag and therefore will not return
/// `CKErrorServerRecordChanged`
///
///
/// All local keys are written to the server, updating the record even if the server record has been modified.
/// Note: This policy should be used with care. Any previously committed change to the server, for example by other devices, will be overwritten by the local value.
/// Keys present only on the server remain unchanged.
/// There are two common ways in which a server record will contain keys not present locally:
/// 1 - Another client may have added a new key to the record since it was fetched.
/// 2 - If
/// `desiredKeys`was used with the fetch / query that returned this record, only a portion of the record's keys may have been downloaded.
/// Note: A
/// `CKShare`record is always treated as
/// `CKRecordSaveIfServerRecordUnchanged,`regardless of the
/// `savePolicy`of the operation that modifies the share.
/// For non-CKShare records, this policy does not compare the record change tag and therefore will not return
/// `CKErrorServerRecordChanged`
///
/// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordsavepolicy?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKRecordSavePolicy(pub NSInteger);
impl CKRecordSavePolicy {
    #[doc(alias = "CKRecordSaveIfServerRecordUnchanged")]
    pub const IfServerRecordUnchanged: Self = Self(0);
    #[doc(alias = "CKRecordSaveChangedKeys")]
    pub const ChangedKeys: Self = Self(1);
    /// Does not compare record change tags
    #[doc(alias = "CKRecordSaveAllKeys")]
    pub const AllKeys: Self = Self(2);
}

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

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

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckmodifyrecordsoperation?language=objc)
    #[unsafe(super(CKDatabaseOperation, CKOperation, NSOperation, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(all(feature = "CKDatabaseOperation", feature = "CKOperation"))]
    pub struct CKModifyRecordsOperation;
);

#[cfg(all(feature = "CKDatabaseOperation", feature = "CKOperation"))]
extern_conformance!(
    unsafe impl NSObjectProtocol for CKModifyRecordsOperation {}
);

#[cfg(all(feature = "CKDatabaseOperation", feature = "CKOperation"))]
impl CKModifyRecordsOperation {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub unsafe fn init(this: Allocated<Self>) -> Retained<Self>;

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID"))]
        #[unsafe(method(initWithRecordsToSave:recordIDsToDelete:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordsToSave_recordIDsToDelete(
            this: Allocated<Self>,
            records: Option<&NSArray<CKRecord>>,
            record_i_ds: Option<&NSArray<CKRecordID>>,
        ) -> Retained<Self>;

        #[cfg(feature = "CKRecord")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordsToSave))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordsToSave(&self) -> Option<Retained<NSArray<CKRecord>>>;

        #[cfg(feature = "CKRecord")]
        /// Setter for [`recordsToSave`][Self::recordsToSave].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setRecordsToSave:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRecordsToSave(&self, records_to_save: Option<&NSArray<CKRecord>>);

        #[cfg(feature = "CKRecordID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordIDsToDelete))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordIDsToDelete(&self) -> Option<Retained<NSArray<CKRecordID>>>;

        #[cfg(feature = "CKRecordID")]
        /// Setter for [`recordIDsToDelete`][Self::recordIDsToDelete].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setRecordIDsToDelete:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setRecordIDsToDelete(
            &self,
            record_i_ds_to_delete: Option<&NSArray<CKRecordID>>,
        );

        /// Determines what data is sent to the server and whether the save should succeed even if the record on the server has changed.
        ///
        ///
        /// :  The default value is
        /// `CKRecordSaveIfServerRecordUnchanged,`which is the recommended value for regular use.
        /// A
        /// `CKShare`record is always treated as
        /// `CKRecordSaveIfServerRecordUnchanged,`regardless of the
        /// `savePolicy`specified.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(savePolicy))]
        #[unsafe(method_family = none)]
        pub unsafe fn savePolicy(&self) -> CKRecordSavePolicy;

        /// Setter for [`savePolicy`][Self::savePolicy].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setSavePolicy:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSavePolicy(&self, save_policy: CKRecordSavePolicy);

        /// This property is kept by the server to identify the last known request from this client.
        /// Multiple requests from the client with the same change token will be ignored by the server.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(clientChangeTokenData))]
        #[unsafe(method_family = none)]
        pub unsafe fn clientChangeTokenData(&self) -> Option<Retained<NSData>>;

        /// Setter for [`clientChangeTokenData`][Self::clientChangeTokenData].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setClientChangeTokenData:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setClientChangeTokenData(&self, client_change_token_data: Option<&NSData>);

        /// Determines whether the batch should fail atomically or not.
        ///
        ///
        /// YES by default.
        /// Server-side write atomicity is only enforced on zones that have
        /// `CKRecordZoneCapabilityAtomic.`If
        /// `isAtomic`is YES, client-side checks are enforced regardless of the zone's capabilities.  (For example, if a record is malformed, and cannot be sent to the server, the client will forcibly fail all other records-to-be-modified in that zone)
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(atomic))]
        #[unsafe(method_family = none)]
        pub unsafe fn atomic(&self) -> bool;

        /// Setter for [`atomic`][Self::atomic].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setAtomic:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setAtomic(&self, atomic: bool);

        #[cfg(all(feature = "CKRecord", feature = "block2"))]
        /// Indicates the progress for each record.
        ///
        ///
        /// This method is called at least once with a progress of 1.0 for every record. Intermediate progress is only reported for records that contain assets.
        /// It is possible for progress to regress when a retry is automatically triggered.
        /// Each
        /// `CKOperation`instance has a private serial queue. This queue is used for all callback block invocations.
        /// This block may share mutable state with other blocks assigned to this operation, but any such mutable state
        /// should not be concurrently used outside of blocks assigned to this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer.
        /// - This might not be thread-safe.
        #[unsafe(method(perRecordProgressBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn perRecordProgressBlock(
            &self,
        ) -> *mut block2::DynBlock<dyn Fn(NonNull<CKRecord>, c_double)>;

        #[cfg(all(feature = "CKRecord", feature = "block2"))]
        /// Setter for [`perRecordProgressBlock`][Self::perRecordProgressBlock].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setPerRecordProgressBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPerRecordProgressBlock(
            &self,
            per_record_progress_block: Option<
                &block2::DynBlock<dyn Fn(NonNull<CKRecord>, c_double)>,
            >,
        );

        #[cfg(all(feature = "CKRecord", feature = "block2"))]
        /// Called on success or failure for each record.
        ///
        ///
        /// Will not be invoked if
        /// `perRecordSaveBlock`is set.
        /// Each
        /// `CKOperation`instance has a private serial queue. This queue is used for all callback block invocations.
        /// This block may share mutable state with other blocks assigned to this operation, but any such mutable state
        /// should not be concurrently used outside of blocks assigned to this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer.
        /// - The returned block's argument 2 must be a valid pointer or null.
        /// - This might not be thread-safe.
        #[deprecated]
        #[unsafe(method(perRecordCompletionBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn perRecordCompletionBlock(
            &self,
        ) -> *mut block2::DynBlock<dyn Fn(NonNull<CKRecord>, *mut NSError)>;

        #[cfg(all(feature = "CKRecord", feature = "block2"))]
        /// Setter for [`perRecordCompletionBlock`][Self::perRecordCompletionBlock].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated]
        #[unsafe(method(setPerRecordCompletionBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPerRecordCompletionBlock(
            &self,
            per_record_completion_block: Option<
                &block2::DynBlock<dyn Fn(NonNull<CKRecord>, *mut NSError)>,
            >,
        );

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID", feature = "block2"))]
        /// Called on success or failure of a record save
        ///
        ///
        /// Following a successful record save, this callback will be invoked with a nonnull
        /// `record,`and a nil
        /// `error.`Following a save failure due to a per-item error (
        /// `CKErrorServerRecordChanged,`for example), this callback will be invoked with a nil
        /// `record,`and a nonnull
        /// `error`Each
        /// `CKOperation`instance has a private serial queue. This queue is used for all callback block invocations.
        /// This block may share mutable state with other blocks assigned to this operation, but any such mutable state
        /// should not be concurrently used outside of blocks assigned to this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer.
        /// - The returned block's argument 2 must be a valid pointer or null.
        /// - The returned block's argument 3 must be a valid pointer or null.
        /// - This might not be thread-safe.
        #[unsafe(method(perRecordSaveBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn perRecordSaveBlock(
            &self,
        ) -> *mut block2::DynBlock<dyn Fn(NonNull<CKRecordID>, *mut CKRecord, *mut NSError)>;

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID", feature = "block2"))]
        /// Setter for [`perRecordSaveBlock`][Self::perRecordSaveBlock].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setPerRecordSaveBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPerRecordSaveBlock(
            &self,
            per_record_save_block: Option<
                &block2::DynBlock<dyn Fn(NonNull<CKRecordID>, *mut CKRecord, *mut NSError)>,
            >,
        );

        #[cfg(all(feature = "CKRecordID", feature = "block2"))]
        /// Called on success or failure of a record deletion
        ///
        /// Each
        /// `CKOperation`instance has a private serial queue. This queue is used for all callback block invocations.
        /// This block may share mutable state with other blocks assigned to this operation, but any such mutable state
        /// should not be concurrently used outside of blocks assigned to this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer.
        /// - The returned block's argument 2 must be a valid pointer or null.
        /// - This might not be thread-safe.
        #[unsafe(method(perRecordDeleteBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn perRecordDeleteBlock(
            &self,
        ) -> *mut block2::DynBlock<dyn Fn(NonNull<CKRecordID>, *mut NSError)>;

        #[cfg(all(feature = "CKRecordID", feature = "block2"))]
        /// Setter for [`perRecordDeleteBlock`][Self::perRecordDeleteBlock].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setPerRecordDeleteBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPerRecordDeleteBlock(
            &self,
            per_record_delete_block: Option<
                &block2::DynBlock<dyn Fn(NonNull<CKRecordID>, *mut NSError)>,
            >,
        );

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID", feature = "block2"))]
        /// This block is called when the operation completes.
        ///
        ///
        /// The
        ///
        /// ```text
        ///  -[NSOperation completionBlock]
        /// ```
        ///
        /// will also be called if both are set.
        /// If the error is
        /// `CKErrorPartialFailure,`the error's userInfo dictionary contains a dictionary of recordIDs to errors keyed off of
        /// `CKPartialErrorsByItemIDKey.``savedRecords,``deletedRecordIDs`and any
        /// `CKPartialErrorsByItemIDKey`errors are repeats of the data sent back in previous
        /// `perRecordSaveBlock`and
        /// `perRecordDeleteBlock`invocations
        /// This call happens as soon as the server has seen all record changes, and may be invoked while the server is processing the side effects of those changes.
        /// Each
        /// `CKOperation`instance has a private serial queue. This queue is used for all callback block invocations.
        /// This block may share mutable state with other blocks assigned to this operation, but any such mutable state
        /// should not be concurrently used outside of blocks assigned to this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer or null.
        /// - The returned block's argument 2 must be a valid pointer or null.
        /// - The returned block's argument 3 must be a valid pointer or null.
        /// - This might not be thread-safe.
        #[unsafe(method(modifyRecordsCompletionBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn modifyRecordsCompletionBlock(
            &self,
        ) -> *mut block2::DynBlock<
            dyn Fn(*mut NSArray<CKRecord>, *mut NSArray<CKRecordID>, *mut NSError),
        >;

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID", feature = "block2"))]
        /// Setter for [`modifyRecordsCompletionBlock`][Self::modifyRecordsCompletionBlock].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setModifyRecordsCompletionBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setModifyRecordsCompletionBlock(
            &self,
            modify_records_completion_block: Option<
                &block2::DynBlock<
                    dyn Fn(*mut NSArray<CKRecord>, *mut NSArray<CKRecordID>, *mut NSError),
                >,
            >,
        );
    );
}

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