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

extern_class!(
    /// A batch of record zone changes that `CKSyncEngine` will send to the server in a single request.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginerecordzonechangebatch?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineRecordZoneChangeBatch;
);

unsafe impl Send for CKSyncEngineRecordZoneChangeBatch {}

unsafe impl Sync for CKSyncEngineRecordZoneChangeBatch {}

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

impl CKSyncEngineRecordZoneChangeBatch {
    extern_methods!(
        #[cfg(all(
            feature = "CKRecord",
            feature = "CKRecordID",
            feature = "CKSyncEngineState",
            feature = "block2"
        ))]
        /// Creates a batch of record zone changes according to a list of pending changes.
        ///
        /// This will iterate over the pending changes in order and add them to the batch until it reaches the max batch size.
        ///
        /// When it sees a pending save, it will ask the record provider for the actual ``CKRecord`` to send to the server.
        /// If you return `nil` from the record provider, this will skip to the next pending change.
        ///
        /// This will return `nil` if there are no pending changes to send.
        ///
        /// # Safety
        ///
        /// `record_provider` block must be sendable.
        #[unsafe(method(initWithPendingChanges:recordProvider:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithPendingChanges_recordProvider(
            this: Allocated<Self>,
            pending_changes: &NSArray<CKSyncEnginePendingRecordZoneChange>,
            record_provider: &block2::DynBlock<dyn Fn(NonNull<CKRecordID>) -> *mut CKRecord + '_>,
        ) -> Option<Retained<Self>>;

        #[cfg(all(feature = "CKRecord", feature = "CKRecordID"))]
        /// Creates a batch of record zone changes to send to the server with a specific set of changes.
        ///
        /// If you'd like to construct your own custom batches of changes to send to the server, you can do so with this initializer.
        ///
        /// ## Batch size limitations
        ///
        /// When creating your own batches, you need to consider batch size limitations.
        /// There is a maximum count and size of records that can be sent to the server in a single batch.
        /// If you supply too many changes, or if the total size of the records is too large, then you might get a ``CKError/limitExceeded``.
        ///
        /// > Tip: These batch size limitations are handled automatically by the ``initWithPendingChanges:recordProvider:`` initializer.
        #[unsafe(method(initWithRecordsToSave:recordIDsToDelete:atomicByZone:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordsToSave_recordIDsToDelete_atomicByZone(
            this: Allocated<Self>,
            records_to_save: Option<&NSArray<CKRecord>>,
            record_i_ds_to_delete: Option<&NSArray<CKRecordID>>,
            atomic_by_zone: bool,
        ) -> Retained<Self>;

        #[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>;

        #[cfg(feature = "CKRecord")]
        /// The records to save to the server.
        #[unsafe(method(recordsToSave))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordsToSave(&self) -> Retained<NSArray<CKRecord>>;

        #[cfg(feature = "CKRecordID")]
        /// The IDs of the records to delete from the server.
        #[unsafe(method(recordIDsToDelete))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordIDsToDelete(&self) -> Retained<NSArray<CKRecordID>>;

        /// If set to true, the sync engine will modify these records atomically by zone.
        ///
        /// If this is true, and if any record change fails, then any other changes from that zone in this batch will also fail with ``CKError/batchRequestFailed``.
        ///
        /// Records that exist in different zones will not be modified together atomically.
        #[unsafe(method(atomicByZone))]
        #[unsafe(method_family = none)]
        pub unsafe fn atomicByZone(&self) -> bool;

        /// Setter for [`atomicByZone`][Self::atomicByZone].
        #[unsafe(method(setAtomicByZone:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setAtomicByZone(&self, atomic_by_zone: bool);
    );
}
