//! 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/cloudkit/ckoperationid?language=objc)
pub type CKOperationID = NSString;

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

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

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

        /// This defines per-operation configuration settings.
        ///
        ///
        /// See the CKOperationConfiguration class description for info on how this configuration composes with CKOperationGroup.defaultConfiguration
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(configuration))]
        #[unsafe(method_family = none)]
        pub unsafe fn configuration(&self) -> Retained<CKOperationConfiguration>;

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

        #[cfg(feature = "CKOperationGroup")]
        /// The group this operation is associated with
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(group))]
        #[unsafe(method_family = none)]
        pub unsafe fn group(&self) -> Option<Retained<CKOperationGroup>>;

        #[cfg(feature = "CKOperationGroup")]
        /// Setter for [`group`][Self::group].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(setGroup:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setGroup(&self, group: Option<&CKOperationGroup>);

        /// This is an identifier unique to this CKOperation.
        ///
        ///
        /// This value is chosen by the system, and will be unique to this instance of a CKOperation.  This identifier will be sent to Apple's servers, and can be used to identify any server-side logging associated with this operation.
        ///
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[unsafe(method(operationID))]
        #[unsafe(method_family = none)]
        pub unsafe fn operationID(&self) -> Retained<CKOperationID>;

        #[cfg(feature = "block2")]
        /// This callback is called after a long lived operation has begun running and is persisted.
        ///
        ///
        /// Once this callback is called the operation will continue running even if the current process exits.
        /// 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
        ///
        /// This might not be thread-safe.
        #[unsafe(method(longLivedOperationWasPersistedBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn longLivedOperationWasPersistedBlock(&self)
            -> *mut block2::DynBlock<dyn Fn()>;

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

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

extern_class!(
    /// An operation configuration is a set of properties that describes how your operation should behave.  All properties have a default value.  When determining what properties to apply to an operation, we consult the operation's configuration property, as well as the operation->group->defaultConfiguration property.  We combine them following these rules:
    ///
    /// ```text
    ///    Group Default Configuration Value | Operation Configuration Value |        Value Applied To Operation
    ///   -----------------------------------+-------------------------------+-----------------------------------------
    ///              default value           |         default value         |                  default value
    ///              default value           |         explicit value        |       operation.configuration explicit value
    ///              explicit value          |         default value         | operation.group.defaultConfiguration explicit value
    ///              explicit value          |         explicit value        |       operation.configuration explicit value
    /// ```
    ///
    /// For example:
    /// CKOperationGroup -> defaultConfiguration -> allowsCellularAccess explicitly set to NO
    /// + CKOperation -> configuration -> allowsCellularAccess has default value of YES
    /// = disallow cellular access
    ///
    /// CKOperationGroup -> defaultConfiguration -> allowsCellularAccess explicitly set to NO
    /// + CKOperation -> configuration -> allowsCellularAccess explicitly set to YES
    /// = allow cellular access
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckoperationconfiguration?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct CKOperationConfiguration;
);

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

impl CKOperationConfiguration {
    extern_methods!(
        #[cfg(feature = "CKContainer")]
        /// If no container is set, [CKContainer defaultContainer] is used
        #[unsafe(method(container))]
        #[unsafe(method_family = none)]
        pub unsafe fn container(&self) -> Option<Retained<CKContainer>>;

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

        /// CKOperations behave differently depending on how you set qualityOfService.
        ///
        ///
        /// ```text
        ///   Quality of Service | timeoutIntervalForResource | Network Error Behavior | Discretionary Behavior
        ///   -------------------+----------------------------+------------------------+-----------------------
        ///   UserInteractive    | -1 (no enforcement)        | fail                   | nonDiscretionary
        ///   UserInitiated      | -1 (no enforcement)        | fail                   | nonDiscretionary
        ///   Default            | 1 week                     | fail                   | discretionary when app backgrounded
        ///   Utility            | 1 week                     | internally retried     | discretionary when app backgrounded
        ///   Background         | 1 week                     | internally retried     | discretionary
        /// ```
        ///
        /// timeoutIntervalForResource
        /// - the timeout interval for any network resources retrieved by this operation
        /// - this can be overridden via CKOperationConfiguration's timeoutIntervalForResource property
        ///
        /// Network Error Behavior
        /// - when a network request in service of a CKOperation fails due to a networking error, the operation may fail with that error, or internally retry the network request.  Only a subset of networking errors are retried, and limiting factors such as timeoutIntervalForResource are still applicable.
        ///
        /// Discretionary Behavior
        /// - network requests in service of a CKOperation may be marked as discretionary
        /// - discretionary network requests are scheduled at the description of the system for optimal performance
        ///
        /// CKOperations have a default qualityOfService of Default.
        #[unsafe(method(qualityOfService))]
        #[unsafe(method_family = none)]
        pub unsafe fn qualityOfService(&self) -> NSQualityOfService;

        /// Setter for [`qualityOfService`][Self::qualityOfService].
        #[unsafe(method(setQualityOfService:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setQualityOfService(&self, quality_of_service: NSQualityOfService);

        /// Defaults to
        /// `YES`
        #[unsafe(method(allowsCellularAccess))]
        #[unsafe(method_family = none)]
        pub unsafe fn allowsCellularAccess(&self) -> bool;

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

        /// Long lived operations will continue running even if your process exits. If your process remains alive for the lifetime of the long lived operation its behavior is the same as a regular operation.
        ///
        /// Long lived operations can be fetched and replayed from the container via the
        /// `fetchAllLongLivedOperations:`and
        /// `fetchLongLivedOperationsWithIDs:`APIs. Your code should only fetch and re-enqueue long lived operations on app launch.
        ///
        /// Long lived operations persist until their -[NSOperation completionBlock] returns or until the operation is cancelled.
        /// Long lived operations may be garbage collected 24 hours after they finish running if no client has replayed them.
        ///
        /// The default value for longLived is NO. Changing the value of longLived on an already started operation or on an outstanding long lived operation fetched from CKContainer has no effect.
        #[unsafe(method(isLongLived))]
        #[unsafe(method_family = none)]
        pub unsafe fn isLongLived(&self) -> bool;

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

        /// If non-zero, overrides the timeout interval for any network requests issued by this operation.
        /// The default value is 60.
        ///
        ///
        /// See: NSURLSessionConfiguration.timeoutIntervalForRequest
        #[unsafe(method(timeoutIntervalForRequest))]
        #[unsafe(method_family = none)]
        pub unsafe fn timeoutIntervalForRequest(&self) -> NSTimeInterval;

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

        /// If set, overrides the timeout interval for any network resources retrieved by this operation.
        /// If not explicitly set, defaults to a value based on the operation's
        /// `qualityOfService`
        ///
        /// See: NSURLSessionConfiguration.timeoutIntervalForResource
        #[unsafe(method(timeoutIntervalForResource))]
        #[unsafe(method_family = none)]
        pub unsafe fn timeoutIntervalForResource(&self) -> NSTimeInterval;

        /// Setter for [`timeoutIntervalForResource`][Self::timeoutIntervalForResource].
        #[unsafe(method(setTimeoutIntervalForResource:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTimeoutIntervalForResource(
            &self,
            timeout_interval_for_resource: NSTimeInterval,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl CKOperationConfiguration {
    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>;
    );
}

/// CKOperationDeprecated.
///
/// These deprecated properties now read and write from the CKOperation's configuration
impl CKOperation {
    extern_methods!(
        #[cfg(feature = "CKContainer")]
        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(container))]
        #[unsafe(method_family = none)]
        pub unsafe fn container(&self) -> Option<Retained<CKContainer>>;

        #[cfg(feature = "CKContainer")]
        /// Setter for [`container`][Self::container].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(setContainer:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setContainer(&self, container: Option<&CKContainer>);

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

        /// Setter for [`allowsCellularAccess`][Self::allowsCellularAccess].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(setAllowsCellularAccess:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setAllowsCellularAccess(&self, allows_cellular_access: bool);

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

        /// Setter for [`isLongLived`][Self::isLongLived].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(setLongLived:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setLongLived(&self, long_lived: bool);

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(timeoutIntervalForRequest))]
        #[unsafe(method_family = none)]
        pub unsafe fn timeoutIntervalForRequest(&self) -> NSTimeInterval;

        /// Setter for [`timeoutIntervalForRequest`][Self::timeoutIntervalForRequest].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(setTimeoutIntervalForRequest:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTimeoutIntervalForRequest(
            &self,
            timeout_interval_for_request: NSTimeInterval,
        );

        /// This property is not atomic.
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(timeoutIntervalForResource))]
        #[unsafe(method_family = none)]
        pub unsafe fn timeoutIntervalForResource(&self) -> NSTimeInterval;

        /// Setter for [`timeoutIntervalForResource`][Self::timeoutIntervalForResource].
        ///
        /// # Safety
        ///
        /// This might not be thread-safe.
        #[deprecated = "Use CKOperationConfiguration"]
        #[unsafe(method(setTimeoutIntervalForResource:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setTimeoutIntervalForResource(
            &self,
            timeout_interval_for_resource: NSTimeInterval,
        );
    );
}
