//! 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 crate::*;

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

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

impl NSThread {
    extern_methods!(
        #[unsafe(method(currentThread))]
        #[unsafe(method_family = none)]
        pub fn currentThread() -> Retained<NSThread>;

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

        /// # Safety
        ///
        /// - `selector` must be a valid selector.
        /// - `target` should be of the correct type.
        /// - `argument` should be of the correct type.
        #[unsafe(method(detachNewThreadSelector:toTarget:withObject:))]
        #[unsafe(method_family = none)]
        pub unsafe fn detachNewThreadSelector_toTarget_withObject(
            selector: Sel,
            target: &AnyObject,
            argument: Option<&AnyObject>,
        );

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

        #[cfg(feature = "NSDictionary")]
        /// # Safety
        ///
        /// The returned generic should be of the correct type.
        #[unsafe(method(threadDictionary))]
        #[unsafe(method_family = none)]
        pub unsafe fn threadDictionary(&self) -> Retained<NSMutableDictionary>;

        #[cfg(feature = "NSDate")]
        #[unsafe(method(sleepUntilDate:))]
        #[unsafe(method_family = none)]
        pub fn sleepUntilDate(date: &NSDate);

        #[cfg(feature = "NSDate")]
        #[unsafe(method(sleepForTimeInterval:))]
        #[unsafe(method_family = none)]
        pub fn sleepForTimeInterval(ti: NSTimeInterval);

        #[unsafe(method(exit))]
        #[unsafe(method_family = none)]
        pub fn exit();

        #[unsafe(method(threadPriority))]
        #[unsafe(method_family = none)]
        pub fn threadPriority_class() -> c_double;

        #[unsafe(method(setThreadPriority:))]
        #[unsafe(method_family = none)]
        pub fn setThreadPriority_class(p: c_double) -> bool;

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

        /// Setter for [`threadPriority`][Self::threadPriority].
        #[unsafe(method(setThreadPriority:))]
        #[unsafe(method_family = none)]
        pub fn setThreadPriority(&self, thread_priority: c_double);

        #[cfg(feature = "NSObjCRuntime")]
        #[unsafe(method(qualityOfService))]
        #[unsafe(method_family = none)]
        pub fn qualityOfService(&self) -> NSQualityOfService;

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

        #[cfg(all(feature = "NSArray", feature = "NSValue"))]
        #[unsafe(method(callStackReturnAddresses))]
        #[unsafe(method_family = none)]
        pub fn callStackReturnAddresses() -> Retained<NSArray<NSNumber>>;

        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        #[unsafe(method(callStackSymbols))]
        #[unsafe(method_family = none)]
        pub fn callStackSymbols() -> Retained<NSArray<NSString>>;

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

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

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

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

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

        #[unsafe(method(isMainThread))]
        #[unsafe(method_family = none)]
        pub fn isMainThread_class() -> bool;

        #[unsafe(method(mainThread))]
        #[unsafe(method_family = none)]
        pub fn mainThread() -> Retained<NSThread>;

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

        /// # Safety
        ///
        /// - `target` should be of the correct type.
        /// - `selector` must be a valid selector.
        /// - `argument` should be of the correct type.
        #[unsafe(method(initWithTarget:selector:object:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithTarget_selector_object(
            this: Allocated<Self>,
            target: &AnyObject,
            selector: Sel,
            argument: Option<&AnyObject>,
        ) -> Retained<Self>;

        #[cfg(feature = "block2")]
        /// # Safety
        ///
        /// `block` block must be sendable.
        #[unsafe(method(initWithBlock:))]
        #[unsafe(method_family = init)]
        pub unsafe fn initWithBlock(
            this: Allocated<Self>,
            block: &block2::DynBlock<dyn Fn()>,
        ) -> Retained<Self>;

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

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

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

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

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

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

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

impl DefaultRetained for NSThread {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nswillbecomemultithreadednotification?language=objc)
    #[cfg(all(feature = "NSNotification", feature = "NSString"))]
    #[deprecated = "This notification does not protect against data races"]
    pub static NSWillBecomeMultiThreadedNotification: &'static NSNotificationName;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsdidbecomesinglethreadednotification?language=objc)
    #[cfg(all(feature = "NSNotification", feature = "NSString"))]
    #[deprecated = "Programs no longer transition to single-threaded mode from threaded environments"]
    pub static NSDidBecomeSingleThreadedNotification: &'static NSNotificationName;
}

extern "C" {
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsthreadwillexitnotification?language=objc)
    #[cfg(all(feature = "NSNotification", feature = "NSString"))]
    #[deprecated = "This notification does not protect against data races"]
    pub static NSThreadWillExitNotification: &'static NSNotificationName;
}

mod private_NSObjectNSThreadPerformAdditions {
    pub trait Sealed {}
}

/// Category "NSThreadPerformAdditions" on [`NSObject`].
#[doc(alias = "NSThreadPerformAdditions")]
pub unsafe trait NSObjectNSThreadPerformAdditions:
    ClassType + Sized + private_NSObjectNSThreadPerformAdditions::Sealed
{
    extern_methods!(
        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelectorOnMainThread:withObject:waitUntilDone:modes:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelectorOnMainThread_withObject_waitUntilDone_modes(
            &self,
            a_selector: Sel,
            arg: Option<&AnyObject>,
            wait: bool,
            array: Option<&NSArray<NSString>>,
        );

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelectorOnMainThread:withObject:waitUntilDone:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelectorOnMainThread_withObject_waitUntilDone(
            &self,
            a_selector: Sel,
            arg: Option<&AnyObject>,
            wait: bool,
        );

        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelector:onThread:withObject:waitUntilDone:modes:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelector_onThread_withObject_waitUntilDone_modes(
            &self,
            a_selector: Sel,
            thr: &NSThread,
            arg: Option<&AnyObject>,
            wait: bool,
            array: Option<&NSArray<NSString>>,
        );

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelector:onThread:withObject:waitUntilDone:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelector_onThread_withObject_waitUntilDone(
            &self,
            a_selector: Sel,
            thr: &NSThread,
            arg: Option<&AnyObject>,
            wait: bool,
        );

        /// # Safety
        ///
        /// - `a_selector` must be a valid selector.
        /// - `arg` should be of the correct type.
        #[unsafe(method(performSelectorInBackground:withObject:))]
        #[unsafe(method_family = none)]
        unsafe fn performSelectorInBackground_withObject(
            &self,
            a_selector: Sel,
            arg: Option<&AnyObject>,
        );
    );
}

impl private_NSObjectNSThreadPerformAdditions::Sealed for NSObject {}
unsafe impl NSObjectNSThreadPerformAdditions for NSObject {}
