//! 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/coredata/nsfetchrequestresulttype?language=objc)
// NS_OPTIONS
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSFetchRequestResultType(pub NSUInteger);
bitflags::bitflags! {
    impl NSFetchRequestResultType: NSUInteger {
        #[doc(alias = "NSManagedObjectResultType")]
        const ManagedObjectResultType = 0x00;
        #[doc(alias = "NSManagedObjectIDResultType")]
        const ManagedObjectIDResultType = 0x01;
        #[doc(alias = "NSDictionaryResultType")]
        const DictionaryResultType = 0x02;
        #[doc(alias = "NSCountResultType")]
        const CountResultType = 0x04;
    }
}

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

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

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/coredata/nsfetchrequestresult?language=objc)
    pub unsafe trait NSFetchRequestResult: NSObjectProtocol {}
);

extern_conformance!(
    unsafe impl NSFetchRequestResult for NSNumber {}
);

extern_conformance!(
    unsafe impl NSFetchRequestResult for NSDictionary {}
);

/// NSFetchedResultSupport.
#[cfg(feature = "NSManagedObject")]
impl NSManagedObject {
    extern_methods!();
}

#[cfg(feature = "NSManagedObject")]
extern_conformance!(
    unsafe impl NSFetchRequestResult for NSManagedObject {}
);

/// NSFetchedResultSupport.
#[cfg(feature = "NSManagedObjectID")]
impl NSManagedObjectID {
    extern_methods!();
}

#[cfg(feature = "NSManagedObjectID")]
extern_conformance!(
    unsafe impl NSFetchRequestResult for NSManagedObjectID {}
);

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/coredata/nsfetchrequest?language=objc)
    #[unsafe(super(NSPersistentStoreRequest, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "NSPersistentStoreRequest")]
    pub struct NSFetchRequest<ResultType: ?Sized = AnyObject>;
);

#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: ?Sized + Message + NSFetchRequestResult> NSFetchRequest<ResultType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewResultType: ?Sized + Message + NSFetchRequestResult>(
        &self,
    ) -> &NSFetchRequest<NewResultType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSPersistentStoreRequest")]
extern_conformance!(
    unsafe impl<ResultType: ?Sized + NSCoding + NSFetchRequestResult> NSCoding
        for NSFetchRequest<ResultType>
    {
    }
);

#[cfg(feature = "NSPersistentStoreRequest")]
extern_conformance!(
    unsafe impl<ResultType: ?Sized + NSFetchRequestResult> NSCopying for NSFetchRequest<ResultType> {}
);

#[cfg(feature = "NSPersistentStoreRequest")]
unsafe impl<ResultType: ?Sized + Message + NSFetchRequestResult> CopyingHelper
    for NSFetchRequest<ResultType>
{
    type Result = Self;
}

#[cfg(feature = "NSPersistentStoreRequest")]
extern_conformance!(
    unsafe impl<ResultType: ?Sized + NSFetchRequestResult> NSObjectProtocol
        for NSFetchRequest<ResultType>
    {
    }
);

#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: Message + NSFetchRequestResult> NSFetchRequest<ResultType> {
    extern_methods!(
        #[unsafe(method(fetchRequestWithEntityName:))]
        #[unsafe(method_family = none)]
        pub unsafe fn fetchRequestWithEntityName(entity_name: &NSString) -> Retained<Self>;

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

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

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

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

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

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

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

        /// Setter for [`predicate`][Self::predicate].
        #[unsafe(method(setPredicate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPredicate(&self, predicate: Option<&NSPredicate>);

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

        /// Setter for [`sortDescriptors`][Self::sortDescriptors].
        #[unsafe(method(setSortDescriptors:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setSortDescriptors(
            &self,
            sort_descriptors: Option<&NSArray<NSSortDescriptor>>,
        );

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

        /// Setter for [`fetchLimit`][Self::fetchLimit].
        #[unsafe(method(setFetchLimit:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setFetchLimit(&self, fetch_limit: NSUInteger);

        #[cfg(feature = "NSPersistentStore")]
        #[unsafe(method(affectedStores))]
        #[unsafe(method_family = none)]
        pub unsafe fn affectedStores(&self) -> Option<Retained<NSArray<NSPersistentStore>>>;

        #[cfg(feature = "NSPersistentStore")]
        /// Setter for [`affectedStores`][Self::affectedStores].
        #[unsafe(method(setAffectedStores:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setAffectedStores(
            &self,
            affected_stores: Option<&NSArray<NSPersistentStore>>,
        );

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

        /// Setter for [`resultType`][Self::resultType].
        #[unsafe(method(setResultType:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setResultType(&self, result_type: NSFetchRequestResultType);

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

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

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

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

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

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

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

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

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

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

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

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

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

        /// Setter for [`propertiesToFetch`][Self::propertiesToFetch].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `properties_to_fetch` generic should be of the correct type.
        #[unsafe(method(setPropertiesToFetch:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPropertiesToFetch(&self, properties_to_fetch: Option<&NSArray>);

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

        /// Setter for [`fetchOffset`][Self::fetchOffset].
        #[unsafe(method(setFetchOffset:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setFetchOffset(&self, fetch_offset: NSUInteger);

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

        /// Setter for [`fetchBatchSize`][Self::fetchBatchSize].
        #[unsafe(method(setFetchBatchSize:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setFetchBatchSize(&self, fetch_batch_size: NSUInteger);

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

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

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

        /// Setter for [`propertiesToGroupBy`][Self::propertiesToGroupBy].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        ///
        /// # Safety
        ///
        /// `properties_to_group_by` generic should be of the correct type.
        #[unsafe(method(setPropertiesToGroupBy:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPropertiesToGroupBy(&self, properties_to_group_by: Option<&NSArray>);

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

        /// Setter for [`havingPredicate`][Self::havingPredicate].
        #[unsafe(method(setHavingPredicate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setHavingPredicate(&self, having_predicate: Option<&NSPredicate>);
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: Message + NSFetchRequestResult> NSFetchRequest<ResultType> {
    extern_methods!(
        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub unsafe fn new() -> Retained<Self>;
    );
}

/// [Apple's documentation](https://developer.apple.com/documentation/coredata/nspersistentstoreasynchronousfetchresultcompletionblock?language=objc)
#[cfg(all(feature = "NSPersistentStoreResult", feature = "block2"))]
pub type NSPersistentStoreAsynchronousFetchResultCompletionBlock =
    *mut block2::DynBlock<dyn Fn(NonNull<NSAsynchronousFetchResult>)>;

extern_class!(
    /// [Apple's documentation](https://developer.apple.com/documentation/coredata/nsasynchronousfetchrequest?language=objc)
    #[unsafe(super(NSPersistentStoreRequest, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "NSPersistentStoreRequest")]
    pub struct NSAsynchronousFetchRequest<ResultType: ?Sized = AnyObject>;
);

#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: ?Sized + Message + NSFetchRequestResult> NSAsynchronousFetchRequest<ResultType> {
    /// Unchecked conversion of the generic parameter.
    ///
    /// # Safety
    ///
    /// The generic must be valid to reinterpret as the given type.
    #[inline]
    pub unsafe fn cast_unchecked<NewResultType: ?Sized + Message + NSFetchRequestResult>(
        &self,
    ) -> &NSAsynchronousFetchRequest<NewResultType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

#[cfg(feature = "NSPersistentStoreRequest")]
extern_conformance!(
    unsafe impl<ResultType: ?Sized + NSFetchRequestResult> NSCopying
        for NSAsynchronousFetchRequest<ResultType>
    {
    }
);

#[cfg(feature = "NSPersistentStoreRequest")]
unsafe impl<ResultType: ?Sized + Message + NSFetchRequestResult> CopyingHelper
    for NSAsynchronousFetchRequest<ResultType>
{
    type Result = Self;
}

#[cfg(feature = "NSPersistentStoreRequest")]
extern_conformance!(
    unsafe impl<ResultType: ?Sized + NSFetchRequestResult> NSObjectProtocol
        for NSAsynchronousFetchRequest<ResultType>
    {
    }
);

#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: Message + NSFetchRequestResult> NSAsynchronousFetchRequest<ResultType> {
    extern_methods!(
        #[unsafe(method(fetchRequest))]
        #[unsafe(method_family = none)]
        pub unsafe fn fetchRequest(&self) -> Retained<NSFetchRequest<ResultType>>;

        #[cfg(all(feature = "NSPersistentStoreResult", feature = "block2"))]
        /// # Safety
        ///
        /// The returned block's argument must be a valid pointer.
        #[unsafe(method(completionBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn completionBlock(
            &self,
        ) -> NSPersistentStoreAsynchronousFetchResultCompletionBlock;

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

        /// Setter for [`estimatedResultCount`][Self::estimatedResultCount].
        #[unsafe(method(setEstimatedResultCount:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setEstimatedResultCount(&self, estimated_result_count: NSInteger);

        #[cfg(all(feature = "NSPersistentStoreResult", feature = "block2"))]
        #[unsafe(method(initWithFetchRequest:completionBlock:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithFetchRequest_completionBlock(
            this: Allocated<Self>,
            request: &NSFetchRequest<ResultType>,
            blk: Option<&block2::DynBlock<dyn Fn(NonNull<NSAsynchronousFetchResult<ResultType>>)>>,
        ) -> Retained<Self>;
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "NSPersistentStoreRequest")]
impl<ResultType: Message + NSFetchRequestResult> NSAsynchronousFetchRequest<ResultType> {
    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>;
    );
}
