//! 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/cloudkit/ckrecordtypeshare?language=objc)
    #[cfg(feature = "CKRecord")]
    pub static CKRecordTypeShare: &'static CKRecordType;
}

extern "C" {
    /// A zone-wide CKShare always uses the record name
    /// `CKRecordNameZoneWideShare.`You can use this to fetch the
    /// `CKShare`record for the zone with a
    /// `CKFetchRecordsOperation.`
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckrecordnamezonewideshare?language=objc)
    pub static CKRecordNameZoneWideShare: &'static NSString;
}

extern "C" {
    /// Value is a string.  Example for a recipe sharing app: "Pot Roast"
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksharetitlekey?language=objc)
    #[cfg(feature = "CKRecord")]
    pub static CKShareTitleKey: &'static CKRecordFieldKey;
}

extern "C" {
    /// Value is a data blob suitable to pass into
    ///
    /// ```text
    ///  -[NSImage imageWithData:] or -[UIImage imageWithData:]
    /// ```
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksharethumbnailimagedatakey?language=objc)
    #[cfg(feature = "CKRecord")]
    pub static CKShareThumbnailImageDataKey: &'static CKRecordFieldKey;
}

extern "C" {
    /// Value is a string representing a UTI.  Example for a recipe sharing app: "com.mycompany.recipe"
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/cksharetypekey?language=objc)
    #[cfg(feature = "CKRecord")]
    pub static CKShareTypeKey: &'static CKRecordFieldKey;
}

extern_class!(
    /// Like CKRecords, CKShares can store arbitrary key-value pairs.  They are modified and fetched in the same manner.
    /// A share, its root record, and its root record's children records will only appear in a participant's CKFetchRecordChangesOperation's results after the share has been accepted by that participant.
    /// Clients have access to the share (and optionally the root record) before accepting a share, via the CKShareMetadata object.  Note that in order to access a root record before accepting a share, you must run a CKFetchShareMetadataOperation requesting the root record.
    /// A CKShare will appear in a CKFetchRecordChangesOperation's results set whenever the participant list is updated.  For that reason, you shouldn't place heavy key-value pairs in it.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/cloudkit/ckshare?language=objc)
    #[unsafe(super(CKRecord, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "CKRecord")]
    pub struct CKShare;
);

#[cfg(feature = "CKRecord")]
extern_conformance!(
    unsafe impl NSCoding for CKShare {}
);

#[cfg(feature = "CKRecord")]
extern_conformance!(
    unsafe impl NSCopying for CKShare {}
);

#[cfg(feature = "CKRecord")]
unsafe impl CopyingHelper for CKShare {
    type Result = Self;
}

#[cfg(feature = "CKRecord")]
extern_conformance!(
    unsafe impl NSObjectProtocol for CKShare {}
);

#[cfg(feature = "CKRecord")]
extern_conformance!(
    unsafe impl NSSecureCoding for CKShare {}
);

#[cfg(feature = "CKRecord")]
impl CKShare {
    extern_methods!(
        /// When saving a newly created CKShare, you must save the share and its rootRecord in the same CKModifyRecordsOperation batch.
        #[unsafe(method(initWithRootRecord:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRootRecord(
            this: Allocated<Self>,
            root_record: &CKRecord,
        ) -> Retained<Self>;

        #[cfg(feature = "CKRecordID")]
        #[unsafe(method(initWithRootRecord:shareID:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRootRecord_shareID(
            this: Allocated<Self>,
            root_record: &CKRecord,
            share_id: &CKRecordID,
        ) -> Retained<Self>;

        #[cfg(feature = "CKRecordZoneID")]
        /// Creates a zone-wide
        /// `CKShare.`A zone-wide
        /// `CKShare`can only exist in a zone with sharing capability
        /// `CKRecordZoneCapabilityZoneWideSharing.`Only one such share can exist in a zone at a time.
        ///
        /// All records in this zone will appear in a participant's
        /// `CKFetchRecordZoneChangesOperation`results in the shared database after the
        /// share has been accepted by the participant.
        ///
        /// Since these shares do not have an associated root record,
        /// `shouldFetchRootRecord`and
        /// `rootRecordDesiredKeys`are always ignored when
        /// running a
        /// `CKFetchShareMetadataOperation`on a zone-wide share URL. Additionally,
        /// `rootRecordID`on the resulting
        /// `CKShareMetadata`is
        /// always absent.
        #[unsafe(method(initWithRecordZoneID:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordZoneID(
            this: Allocated<Self>,
            record_zone_id: &CKRecordZoneID,
        ) -> Retained<Self>;

        /// # Safety
        ///
        /// `a_decoder` possibly has further requirements.
        #[unsafe(method(initWithCoder:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithCoder(this: Allocated<Self>, a_decoder: &NSCoder) -> Retained<Self>;

        #[cfg(feature = "CKShareParticipant")]
        /// Defines what permission a user has when not explicitly added to the share.
        ///
        ///
        /// Shares with
        /// `publicPermission`more permissive than
        /// `CKShareParticipantPermissionNone`can be joined by any user with access to the share's shareURL.
        /// By default, public permission is
        /// `CKShareParticipantPermissionNone.`Changing the public permission to
        /// `CKShareParticipantPermissionReadOnly`or
        /// `CKShareParticipantPermissionReadWrite`will result in all pending participants being removed.  Already-accepted participants will remain on the share.
        /// Changing the public permission to
        /// `CKShareParticipantPermissionNone`will result in all participants being removed from the share.  You may subsequently choose to call
        /// `addParticipant:`before saving the share, those participants will be added to the share.
        #[unsafe(method(publicPermission))]
        #[unsafe(method_family = none)]
        pub unsafe fn publicPermission(&self) -> CKShareParticipantPermission;

        #[cfg(feature = "CKShareParticipant")]
        /// Setter for [`publicPermission`][Self::publicPermission].
        #[unsafe(method(setPublicPermission:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setPublicPermission(&self, public_permission: CKShareParticipantPermission);

        /// A URL that can be used to invite participants to this share.
        ///
        ///
        /// Only available after share record has been saved to the server.  This url is stable, and is tied to the rootRecord.  That is, if you share a rootRecord, delete the share, and re-share the same rootRecord via a newly created share, that newly created share's url will be identical to the prior share's url
        #[unsafe(method(URL))]
        #[unsafe(method_family = none)]
        pub unsafe fn URL(&self) -> Option<Retained<NSURL>>;

        #[cfg(feature = "CKShareParticipant")]
        /// All participants on the share that the current user has permissions to see.
        ///
        ///
        /// At the minimum that will include the owner and the current user.
        #[unsafe(method(participants))]
        #[unsafe(method_family = none)]
        pub unsafe fn participants(&self) -> Retained<NSArray<CKShareParticipant>>;

        #[cfg(feature = "CKShareParticipant")]
        /// Convenience methods for fetching special users from the participant array
        #[unsafe(method(owner))]
        #[unsafe(method_family = none)]
        pub unsafe fn owner(&self) -> Retained<CKShareParticipant>;

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

        #[cfg(feature = "CKShareParticipant")]
        /// If a participant with a matching userIdentity already exists, then that existing participant's properties will be updated; no new participant will be added.
        /// A ``CKShareParticipant`` instance that has already been added to one ``CKShare`` cannot be added to another, unless it is removed from the first ``CKShare`` through `removeParticipant`.
        /// In order to modify the list of participants, a share must have publicPermission set to
        /// `CKShareParticipantPermissionNone.`That is, you cannot mix-and-match private users and public users in the same share.
        ///
        /// See: CKShareParticipantRole
        #[unsafe(method(addParticipant:))]
        #[unsafe(method_family = none)]
        pub unsafe fn addParticipant(&self, participant: &CKShareParticipant);

        #[cfg(feature = "CKShareParticipant")]
        /// It's not allowed to call `removeParticipant` on a ``CKShare`` with a ``CKShareParticipant`` that has never been added to that share through `addParticipant`.
        #[unsafe(method(removeParticipant:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeParticipant(&self, participant: &CKShareParticipant);

        /// Invitation URLs that can be used by any receiver to claim the associated participantID and join the share.
        ///
        /// Only available after a share record has been saved to the server for participants created via ``CKShareParticipant/oneTimeURLParticipant``.
        /// One-time URLs are stable, and tied to the associated participantIDs as long as the participant is part of the share.
        /// Typically, a recipient user invited via their handle is provided a ``URL`` directly by the share's owner.
        /// However, any user can also use a one-time URL in the same manner to fetch share metadata and accept the share.
        /// After share acceptance, the one-time URL becomes functionally equivalent to the regular ``URL``.
        ///
        /// - Parameters:
        /// - participantID: The ``CKShareParticipant/participantID`` corresponding to the ``CKShareParticipant/oneTimeURLParticipant`` added to the share.
        #[unsafe(method(oneTimeURLForParticipantID:))]
        #[unsafe(method_family = none)]
        pub unsafe fn oneTimeURLForParticipantID(
            &self,
            participant_id: &NSString,
        ) -> Option<Retained<NSURL>>;

        /// These superclass-provided initializers are not allowed for CKShare
        #[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>;

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

        #[cfg(feature = "CKRecordID")]
        #[unsafe(method(initWithRecordType:recordID:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordType_recordID(
            this: Allocated<Self>,
            record_type: &CKRecordType,
            record_id: &CKRecordID,
        ) -> Retained<Self>;

        #[cfg(feature = "CKRecordZoneID")]
        #[unsafe(method(initWithRecordType:zoneID:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithRecordType_zoneID(
            this: Allocated<Self>,
            record_type: &CKRecordType,
            zone_id: &CKRecordZoneID,
        ) -> Retained<Self>;

        #[cfg(feature = "CKShareAccessRequester")]
        /// A list of all uninvited users who have requested access to this share.
        ///
        /// When share access requests are allowed, uninvited users can request to join the share.
        /// All pending access requests appear in this array. Each requester is returned with name components
        /// and either an email or phone number.
        ///
        /// Either share owners or administrators can respond to these access requests.
        ///
        /// ### Responding to Access Requests:
        ///
        /// - **Approve Requesters:**
        /// - Fetch the participant information by running ``CKFetchShareParticipantsOperation`` with
        /// the requester's ``CKShareAccessRequester/participantLookupInfo``.
        /// - Add the resulting participant to the share.
        ///
        /// - **Deny Requesters:**
        /// - Use ``CloudKit/CKShare/denyRequesters:`` to remove the requester from the requesters list.
        ///
        /// - **Block Requesters:**
        /// - Use ``CloudKit/CKShare/blockRequesters:`` to block requesters.
        /// - Blocking a requester prevents them from sending future access requests to the share.
        #[unsafe(method(requesters))]
        #[unsafe(method_family = none)]
        pub unsafe fn requesters(&self) -> Retained<NSArray<CKShareAccessRequester>>;

        #[cfg(feature = "CKShareBlockedIdentity")]
        /// A list of users blocked from requesting access to this share.
        ///
        /// Identities remain in this list until an owner or administrator calls ``CloudKit/CKShare/unblockIdentities:``.
        #[unsafe(method(blockedIdentities))]
        #[unsafe(method_family = none)]
        pub unsafe fn blockedIdentities(&self) -> Retained<NSArray<CKShareBlockedIdentity>>;

        /// Indicates whether uninvited users can request access to this share.
        ///
        /// By default, this property is set to `NO`. When set to `YES`, uninvited users can request
        /// access to the share if they discover the share URL. When set to `NO`, the server prevents uninvited users
        /// from requesting access and does not indicate whether the share exists.
        ///
        /// Only the share owner or an administrator can modify this property. Attempts by other participants
        /// to modify this property result in an exception.
        #[unsafe(method(allowsAccessRequests))]
        #[unsafe(method_family = none)]
        pub unsafe fn allowsAccessRequests(&self) -> bool;

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

        #[cfg(feature = "CKShareAccessRequester")]
        /// Denies access requests from specified users.
        ///
        /// Use this method to deny pending access requests from uninvited users. Denied requesters are removed
        /// from the ``CloudKit/CKShare/requesters`` array. To persist the changes, save the share to the server
        /// after calling this method.
        ///
        /// After denial, requesters can still submit new access requests unless explicitly blocked using
        /// ``CloudKit/CKShare/blockRequesters:``.
        ///
        /// Only the share owner or an administrator can invoke this method. Attempts by other participants
        /// result in an exception.
        ///
        /// - Parameter requesters: An array of ``CKShareAccessRequester`` objects to deny.
        #[unsafe(method(denyRequesters:))]
        #[unsafe(method_family = none)]
        pub unsafe fn denyRequesters(&self, requesters: &NSArray<CKShareAccessRequester>);

        #[cfg(feature = "CKShareAccessRequester")]
        /// Blocks specified users from requesting access to this share.
        ///
        /// Blocking prevents users from submitting future access requests and removes existing participants from the share.
        /// Blocked requesters appear in the ``CloudKit/CKShare/blockedIdentities`` array.
        ///
        /// To persist this change, save the share to the server after calling this method.
        ///
        /// Only the share owner or an administrator can invoke this method. Attempts by other participants
        /// result in an exception.
        ///
        /// - Parameter requesters: An array of ``CKShareAccessRequester`` objects to block.
        #[unsafe(method(blockRequesters:))]
        #[unsafe(method_family = none)]
        pub unsafe fn blockRequesters(&self, requesters: &NSArray<CKShareAccessRequester>);

        #[cfg(feature = "CKShareBlockedIdentity")]
        /// Unblocks previously blocked users, allowing them to request access again.
        ///
        /// Use this method to remove specified identities from the ``CloudKit/CKShare/blockedIdentities`` array.
        /// Unblocked identities can request access again if access requests are enabled.
        ///
        /// To persist this change, save the share to the server after calling this method.
        ///
        /// Only the share owner or an administrator can invoke this method. Attempts by other participants
        /// result in an exception.
        ///
        /// - Parameter blockedIdentities: An array of ``CKShareBlockedIdentity`` objects to unblock.
        #[unsafe(method(unblockIdentities:))]
        #[unsafe(method_family = none)]
        pub unsafe fn unblockIdentities(
            &self,
            blocked_identities: &NSArray<CKShareBlockedIdentity>,
        );
    );
}
