//! 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!(
    /// An object that tracks some state required for proper and efficient operation of ``CKSyncEngine-5sie5``.
    ///
    /// ``CKSyncEngine-5sie5`` needs to track several things in order to properly sync.
    /// For example, it needs to remember the last server change tokens for your database and zones.
    /// It also needs to keep track of things like the last known user record ID and other various pieces of state.
    ///
    /// A lot of this state is hidden internally, but some of it you can control.
    ///
    /// ## Pending changes
    ///
    /// One of the main things you can control is the list of pending changes to send to the server.
    /// You can control these by calling functions like ``addPendingDatabaseChanges:`` and ``addPendingRecordZoneChanges:``.
    /// When you add new pending changes, the sync engine will automatically schedule a task to sync with the server.
    ///
    /// ## State serialization
    ///
    /// ``CKSyncEngine-5sie5`` will occasionally update its state in the background.
    /// When it updates its state, your delegate will receive a ``CKSyncEngineStateUpdateEvent``.
    ///
    /// This event will contain a ``CKSyncEngineStateSerialization``, which you should persist locally.
    /// The next time your process launches, you initialize your sync engine with the last state serialization you received.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginestate?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineState;
);

unsafe impl Send for CKSyncEngineState {}

unsafe impl Sync for CKSyncEngineState {}

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

impl CKSyncEngineState {
    extern_methods!(
        #[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>;

        /// A list of record changes that need to be sent to the server.
        ///
        /// ``CKSyncEngine-5sie5`` provides the convenience of tracking your pending record zone changes.
        /// When the user makes some changes that need to be sent to the server, you can track them in this list.
        /// Then, you can use this list when creating your next ``CKSyncEngineRecordZoneChangeBatch`` in your ``CKSyncEngineDelegate-1q7g8``.
        ///
        /// The sync engine will ensure consistency and deduplicate these pending changes under the hood.
        /// For example, if you add a pending save for record A, then record B, then record A again, this will result in a list of `[saveRecordA, saveRecordB]`.
        /// Similarly, if you add a pending save for record A, then add a pending delete for the same record A, this will result in a single pending change of `[deleteRecordA]`.
        ///
        /// The sync engine will manage this list while it sends changes to the server.
        /// For example, when it successfully saves a record, it will remove that change from this list.
        /// If it fails to send a change due to some retryable error (e.g. a network failure), it will keep that change in this list.
        ///
        /// If you'd prefer to track pending changes yourself, you can use ``CKSyncEngine/State/hasPendingUntrackedChanges`` instead.
        #[unsafe(method(pendingRecordZoneChanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn pendingRecordZoneChanges(
            &self,
        ) -> Retained<NSArray<CKSyncEnginePendingRecordZoneChange>>;

        /// A list of database changes that need to be sent to the server, similar to `pendingRecordZoneChanges`.
        #[unsafe(method(pendingDatabaseChanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn pendingDatabaseChanges(
            &self,
        ) -> Retained<NSArray<CKSyncEnginePendingDatabaseChange>>;

        /// This represents whether or not you have pending changes to send to the server that aren't tracked in ``CKSyncEngine/State/pendingRecordZoneChanges``.
        /// This is useful if you want to track pending changes in your own local database instead of the sync engine state.
        ///
        /// When this property is set, the sync engine will automatically schedule a sync.
        /// When the sync task runs, it will ask your delegate for pending changes in ``CKSyncEngineDelegate/nextRecordZoneChangeBatch(_:syncEngine:)``.
        #[unsafe(method(hasPendingUntrackedChanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn hasPendingUntrackedChanges(&self) -> bool;

        /// Setter for [`hasPendingUntrackedChanges`][Self::hasPendingUntrackedChanges].
        #[unsafe(method(setHasPendingUntrackedChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setHasPendingUntrackedChanges(&self, has_pending_untracked_changes: bool);

        #[cfg(feature = "CKRecordZoneID")]
        /// The list of zone IDs that have new changes to fetch from the server.
        /// ``CKSyncEngine-5sie5`` keeps track of these zones and will update this list as it receives new information.
        #[unsafe(method(zoneIDsWithUnfetchedServerChanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneIDsWithUnfetchedServerChanges(&self)
            -> Retained<NSArray<CKRecordZoneID>>;

        /// Adds to the list of pending record zone changes.
        ///
        /// When you add a new pending change, the sync engine will automatically schedule a sync task.
        ///
        /// The sync engine will ensure consistency and deduplicate these changes under the hood.
        #[unsafe(method(addPendingRecordZoneChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addPendingRecordZoneChanges(
            &self,
            changes: &NSArray<CKSyncEnginePendingRecordZoneChange>,
        );

        /// Removes from the list of pending record zone changes.
        #[unsafe(method(removePendingRecordZoneChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removePendingRecordZoneChanges(
            &self,
            changes: &NSArray<CKSyncEnginePendingRecordZoneChange>,
        );

        /// Adds to the list of pending database changes.
        ///
        /// When you add a new pending change, the sync engine will automatically schedule a sync task.
        ///
        /// The sync engine will ensure consistency and deduplicate these changes under the hood.
        #[unsafe(method(addPendingDatabaseChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addPendingDatabaseChanges(
            &self,
            changes: &NSArray<CKSyncEnginePendingDatabaseChange>,
        );

        /// Removes from the list of pending database changes.
        #[unsafe(method(removePendingDatabaseChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removePendingDatabaseChanges(
            &self,
            changes: &NSArray<CKSyncEnginePendingDatabaseChange>,
        );
    );
}

extern_class!(
    /// A serialized representation of a ``CKSyncEngineState``.
    ///
    /// This will be passed to your delegate via ``CKSyncEngine/Event/StateUpdate``.
    /// You should use `NSSecureCoding` to persist this locally alongside your other data and use it the next time you initialize your sync engine.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginestateserialization?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEngineStateSerialization;
);

unsafe impl Send for CKSyncEngineStateSerialization {}

unsafe impl Sync for CKSyncEngineStateSerialization {}

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

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

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

impl CKSyncEngineStateSerialization {
    extern_methods!(
        #[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>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingrecordzonechangetype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKSyncEnginePendingRecordZoneChangeType(pub NSInteger);
impl CKSyncEnginePendingRecordZoneChangeType {
    #[doc(alias = "CKSyncEnginePendingRecordZoneChangeTypeSaveRecord")]
    pub const SaveRecord: Self = Self(0);
    #[doc(alias = "CKSyncEnginePendingRecordZoneChangeTypeDeleteRecord")]
    pub const DeleteRecord: Self = Self(1);
}

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

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

extern_class!(
    /// A change in a record zone that needs to be sent to the server.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingrecordzonechange?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEnginePendingRecordZoneChange;
);

unsafe impl Send for CKSyncEnginePendingRecordZoneChange {}

unsafe impl Sync for CKSyncEnginePendingRecordZoneChange {}

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

impl CKSyncEnginePendingRecordZoneChange {
    extern_methods!(
        #[cfg(feature = "CKRecordID")]
        #[unsafe(method(initWithRecordID:type:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordID_type(
            this: Allocated<Self>,
            record_id: &CKRecordID,
            r#type: CKSyncEnginePendingRecordZoneChangeType,
        ) -> 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 = "CKRecordID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(recordID))]
        #[unsafe(method_family = none)]
        pub unsafe fn recordID(&self) -> Retained<CKRecordID>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub unsafe fn r#type(&self) -> CKSyncEnginePendingRecordZoneChangeType;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingdatabasechangetype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct CKSyncEnginePendingDatabaseChangeType(pub NSInteger);
impl CKSyncEnginePendingDatabaseChangeType {
    #[doc(alias = "CKSyncEnginePendingDatabaseChangeTypeSaveZone")]
    pub const SaveZone: Self = Self(0);
    #[doc(alias = "CKSyncEnginePendingDatabaseChangeTypeDeleteZone")]
    pub const DeleteZone: Self = Self(1);
}

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

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

extern_class!(
    /// A change in a database that needs to be sent to the server.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingdatabasechange?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEnginePendingDatabaseChange;
);

unsafe impl Send for CKSyncEnginePendingDatabaseChange {}

unsafe impl Sync for CKSyncEnginePendingDatabaseChange {}

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

impl CKSyncEnginePendingDatabaseChange {
    extern_methods!(
        #[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 = "CKRecordZoneID")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(zoneID))]
        #[unsafe(method_family = none)]
        pub unsafe fn zoneID(&self) -> Retained<CKRecordZoneID>;

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(type))]
        #[unsafe(method_family = none)]
        pub unsafe fn r#type(&self) -> CKSyncEnginePendingDatabaseChangeType;
    );
}

extern_class!(
    /// A zone save that needs to be sent to the server.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingzonesave?language=objc)
    #[unsafe(super(CKSyncEnginePendingDatabaseChange, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEnginePendingZoneSave;
);

unsafe impl Send for CKSyncEnginePendingZoneSave {}

unsafe impl Sync for CKSyncEnginePendingZoneSave {}

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

impl CKSyncEnginePendingZoneSave {
    extern_methods!(
        #[cfg(feature = "CKRecordZone")]
        #[unsafe(method(initWithZone:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithZone(this: Allocated<Self>, zone: &CKRecordZone) -> Retained<Self>;

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

/// Methods declared on superclass `CKSyncEnginePendingDatabaseChange`.
impl CKSyncEnginePendingZoneSave {
    extern_methods!(
        #[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>;
    );
}

extern_class!(
    /// A zone delete that needs to be sent to the server.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksyncenginependingzonedelete?language=objc)
    #[unsafe(super(CKSyncEnginePendingDatabaseChange, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKSyncEnginePendingZoneDelete;
);

unsafe impl Send for CKSyncEnginePendingZoneDelete {}

unsafe impl Sync for CKSyncEnginePendingZoneDelete {}

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

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

/// Methods declared on superclass `CKSyncEnginePendingDatabaseChange`.
impl CKSyncEnginePendingZoneDelete {
    extern_methods!(
        #[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>;
    );
}
