//! 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 "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontextwillsavenotification?language=objc)
    pub static NSManagedObjectContextWillSaveNotification: &'static NSString;
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/// [Apple's documentation](https://developer.apple.com/documentation/coredata/nsmanagedobjectcontextconcurrencytype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSManagedObjectContextConcurrencyType(pub NSUInteger);
impl NSManagedObjectContextConcurrencyType {
    #[doc(alias = "NSConfinementConcurrencyType")]
    #[deprecated = "Use another NSManagedObjectContextConcurrencyType"]
    pub const ConfinementConcurrencyType: Self = Self(0x00);
    #[doc(alias = "NSPrivateQueueConcurrencyType")]
    pub const PrivateQueueConcurrencyType: Self = Self(0x01);
    #[doc(alias = "NSMainQueueConcurrencyType")]
    pub const MainQueueConcurrencyType: Self = Self(0x02);
}

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

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

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

unsafe impl Send for NSManagedObjectContext {}

unsafe impl Sync for NSManagedObjectContext {}

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

extern_conformance!(
    unsafe impl NSLocking for NSManagedObjectContext {}
);

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

impl NSManagedObjectContext {
    extern_methods!(
        #[deprecated = "Use -initWithConcurrencyType: instead"]
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;

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

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

        #[cfg(feature = "block2")]
        /// # Safety
        ///
        /// `block` block must be sendable.
        #[unsafe(method(performBlock:))]
        #[unsafe(method_family = none)]
        pub unsafe fn performBlock(&self, block: &block2::DynBlock<dyn Fn()>);

        #[cfg(feature = "block2")]
        /// # Safety
        ///
        /// `block` block must be sendable.
        #[unsafe(method(performBlockAndWait:))]
        #[unsafe(method_family = none)]
        pub unsafe fn performBlockAndWait(&self, block: &block2::DynBlock<dyn Fn() + '_>);

        #[cfg(feature = "NSPersistentStoreCoordinator")]
        #[unsafe(method(persistentStoreCoordinator))]
        #[unsafe(method_family = none)]
        pub unsafe fn persistentStoreCoordinator(
            &self,
        ) -> Option<Retained<NSPersistentStoreCoordinator>>;

        #[cfg(feature = "NSPersistentStoreCoordinator")]
        /// Setter for [`persistentStoreCoordinator`][Self::persistentStoreCoordinator].
        #[unsafe(method(setPersistentStoreCoordinator:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPersistentStoreCoordinator(
            &self,
            persistent_store_coordinator: Option<&NSPersistentStoreCoordinator>,
        );

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

        /// Setter for [`parentContext`][Self::parentContext].
        #[unsafe(method(setParentContext:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setParentContext(&self, parent_context: Option<&NSManagedObjectContext>);

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

        /// Setter for [`name`][Self::name].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setName:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setName(&self, name: Option<&NSString>);

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(undoManager))]
        #[unsafe(method_family = none)]
        pub unsafe fn undoManager(&self, mtm: MainThreadMarker) -> Option<Retained<NSUndoManager>>;

        /// Setter for [`undoManager`][Self::undoManager].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setUndoManager:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setUndoManager(&self, undo_manager: Option<&NSUndoManager>);

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

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// - The returned generic should be of the correct type.
        /// - This might not be thread-safe.
        #[unsafe(method(userInfo))]
        #[unsafe(method_family = none)]
        pub unsafe fn userInfo(&self) -> Retained<NSMutableDictionary>;

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

        #[cfg(all(feature = "NSManagedObject", feature = "NSManagedObjectID"))]
        #[unsafe(method(objectRegisteredForID:))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectRegisteredForID(
            &self,
            object_id: &NSManagedObjectID,
        ) -> Option<Retained<NSManagedObject>>;

        #[cfg(all(feature = "NSManagedObject", feature = "NSManagedObjectID"))]
        #[unsafe(method(objectWithID:))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectWithID(
            &self,
            object_id: &NSManagedObjectID,
        ) -> Retained<NSManagedObject>;

        #[cfg(all(feature = "NSManagedObject", feature = "NSManagedObjectID"))]
        #[unsafe(method(existingObjectWithID:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn existingObjectWithID_error(
            &self,
            object_id: &NSManagedObjectID,
        ) -> Result<Retained<NSManagedObject>, Retained<NSError>>;

        #[cfg(all(feature = "NSFetchRequest", feature = "NSPersistentStoreRequest"))]
        /// # Safety
        ///
        /// `request` generic should be bound by `NSFetchRequestResult`.
        #[unsafe(method(executeFetchRequest:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn executeFetchRequest_error(
            &self,
            request: &NSFetchRequest,
        ) -> Result<Retained<NSArray>, Retained<NSError>>;

        #[cfg(all(
            feature = "NSPersistentStoreRequest",
            feature = "NSPersistentStoreResult"
        ))]
        #[unsafe(method(executeRequest:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn executeRequest_error(
            &self,
            request: &NSPersistentStoreRequest,
        ) -> Result<Retained<NSPersistentStoreResult>, Retained<NSError>>;

        #[cfg(feature = "NSManagedObject")]
        #[unsafe(method(insertObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn insertObject(&self, object: &NSManagedObject);

        #[cfg(feature = "NSManagedObject")]
        #[unsafe(method(deleteObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn deleteObject(&self, object: &NSManagedObject);

        #[cfg(feature = "NSManagedObject")]
        #[unsafe(method(refreshObject:mergeChanges:))]
        #[unsafe(method_family = none)]
        pub unsafe fn refreshObject_mergeChanges(&self, object: &NSManagedObject, flag: bool);

        #[cfg(feature = "NSManagedObject")]
        #[unsafe(method(detectConflictsForObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn detectConflictsForObject(&self, object: &NSManagedObject);

        /// # Safety
        ///
        /// - `object` should be of the correct type.
        /// - `change` generic should be of the correct type.
        /// - `context` must be a valid pointer or null.
        #[unsafe(method(observeValueForKeyPath:ofObject:change:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn observeValueForKeyPath_ofObject_change_context(
            &self,
            key_path: Option<&NSString>,
            object: Option<&AnyObject>,
            change: Option<&NSDictionary<NSString, AnyObject>>,
            context: *mut c_void,
        );

        #[unsafe(method(processPendingChanges))]
        #[unsafe(method_family = none)]
        pub unsafe fn processPendingChanges(&self);

        #[cfg(feature = "NSPersistentStore")]
        /// # Safety
        ///
        /// `object` should be of the correct type.
        #[unsafe(method(assignObject:toPersistentStore:))]
        #[unsafe(method_family = none)]
        pub unsafe fn assignObject_toPersistentStore(
            &self,
            object: &AnyObject,
            store: &NSPersistentStore,
        );

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

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

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

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

        #[unsafe(method(undo))]
        #[unsafe(method_family = none)]
        pub unsafe fn undo(&self);

        #[unsafe(method(redo))]
        #[unsafe(method_family = none)]
        pub unsafe fn redo(&self);

        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub unsafe fn reset(&self);

        #[unsafe(method(rollback))]
        #[unsafe(method_family = none)]
        pub unsafe fn rollback(&self);

        #[unsafe(method(save:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn save(&self) -> Result<(), Retained<NSError>>;

        #[unsafe(method(refreshAllObjects))]
        #[unsafe(method_family = none)]
        pub unsafe fn refreshAllObjects(&self);

        #[deprecated = "Use a queue style context and -performBlockAndWait: instead"]
        #[unsafe(method(lock))]
        #[unsafe(method_family = none)]
        pub unsafe fn lock(&self);

        #[deprecated = "Use a queue style context and -performBlockAndWait: instead"]
        #[unsafe(method(unlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn unlock(&self);

        #[deprecated = "Use a queue style context and -performBlock: instead"]
        #[unsafe(method(tryLock))]
        #[unsafe(method_family = none)]
        pub unsafe fn tryLock(&self) -> bool;

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

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

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

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

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

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

        #[cfg(all(
            feature = "NSManagedObject",
            feature = "NSManagedObjectID",
            feature = "NSPropertyDescription"
        ))]
        #[unsafe(method(shouldHandleInaccessibleFault:forObjectID:triggeredByProperty:))]
        #[unsafe(method_family = none)]
        pub unsafe fn shouldHandleInaccessibleFault_forObjectID_triggeredByProperty(
            &self,
            fault: &NSManagedObject,
            oid: &NSManagedObjectID,
            property: Option<&NSPropertyDescription>,
        ) -> bool;

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

        /// Setter for [`stalenessInterval`][Self::stalenessInterval].
        #[unsafe(method(setStalenessInterval:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setStalenessInterval(&self, staleness_interval: NSTimeInterval);

        #[unsafe(method(mergePolicy))]
        #[unsafe(method_family = none)]
        pub unsafe fn mergePolicy(&self) -> Retained<AnyObject>;

        /// Setter for [`mergePolicy`][Self::mergePolicy].
        ///
        /// # Safety
        ///
        /// `merge_policy` should be of the correct type.
        #[unsafe(method(setMergePolicy:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setMergePolicy(&self, merge_policy: &AnyObject);

        #[cfg(feature = "NSManagedObject")]
        #[unsafe(method(obtainPermanentIDsForObjects:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn obtainPermanentIDsForObjects_error(
            &self,
            objects: &NSArray<NSManagedObject>,
        ) -> Result<(), Retained<NSError>>;

        #[unsafe(method(mergeChangesFromContextDidSaveNotification:))]
        #[unsafe(method_family = none)]
        pub unsafe fn mergeChangesFromContextDidSaveNotification(
            &self,
            notification: &NSNotification,
        );

        /// # Safety
        ///
        /// `change_notification_data` generic should be of the correct type.
        #[unsafe(method(mergeChangesFromRemoteContextSave:intoContexts:))]
        #[unsafe(method_family = none)]
        pub unsafe fn mergeChangesFromRemoteContextSave_intoContexts(
            change_notification_data: &NSDictionary,
            contexts: &NSArray<NSManagedObjectContext>,
        );

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

        #[cfg(feature = "NSQueryGenerationToken")]
        #[unsafe(method(setQueryGenerationFromToken:error:_))]
        #[unsafe(method_family = none)]
        pub unsafe fn setQueryGenerationFromToken_error(
            &self,
            generation: Option<&NSQueryGenerationToken>,
        ) -> Result<(), Retained<NSError>>;

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

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

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

        /// Setter for [`transactionAuthor`][Self::transactionAuthor].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setTransactionAuthor:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTransactionAuthor(&self, transaction_author: Option<&NSString>);
    );
}
