//! 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/nscache?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSCache<KeyType: ?Sized = AnyObject, ObjectType: ?Sized = AnyObject>;
);

impl<KeyType: ?Sized + Message, ObjectType: ?Sized + Message> NSCache<KeyType, ObjectType> {
    /// Unchecked conversion of the generic parameters.
    ///
    /// # Safety
    ///
    /// The generics must be valid to reinterpret as the given types.
    #[inline]
    pub unsafe fn cast_unchecked<NewKeyType: ?Sized + Message, NewObjectType: ?Sized + Message>(
        &self,
    ) -> &NSCache<NewKeyType, NewObjectType> {
        unsafe { &*((self as *const Self).cast()) }
    }
}

extern_conformance!(
    unsafe impl<KeyType: ?Sized, ObjectType: ?Sized> NSObjectProtocol for NSCache<KeyType, ObjectType> {}
);

impl<KeyType: Message, ObjectType: Message> NSCache<KeyType, ObjectType> {
    extern_methods!(
        #[cfg(feature = "NSString")]
        #[unsafe(method(name))]
        #[unsafe(method_family = none)]
        pub unsafe fn name(&self) -> 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 unsafe fn setName(&self, name: &NSString);

        /// # Safety
        ///
        /// This is not retained internally, you must ensure the object is still alive.
        #[unsafe(method(delegate))]
        #[unsafe(method_family = none)]
        pub unsafe fn delegate(&self) -> Option<Retained<ProtocolObject<dyn NSCacheDelegate>>>;

        /// Setter for [`delegate`][Self::delegate].
        ///
        /// # Safety
        ///
        /// This is unretained, you must ensure the object is kept alive while in use.
        #[unsafe(method(setDelegate:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setDelegate(&self, delegate: Option<&ProtocolObject<dyn NSCacheDelegate>>);

        #[unsafe(method(objectForKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn objectForKey(&self, key: &KeyType) -> Option<Retained<ObjectType>>;

        #[unsafe(method(setObject:forKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_forKey(&self, obj: &ObjectType, key: &KeyType);

        #[unsafe(method(setObject:forKey:cost:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setObject_forKey_cost(&self, obj: &ObjectType, key: &KeyType, g: NSUInteger);

        #[unsafe(method(removeObjectForKey:))]
        #[unsafe(method_family = none)]
        pub unsafe fn removeObjectForKey(&self, key: &KeyType);

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

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

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

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

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

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

        /// Setter for [`evictsObjectsWithDiscardedContent`][Self::evictsObjectsWithDiscardedContent].
        #[unsafe(method(setEvictsObjectsWithDiscardedContent:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setEvictsObjectsWithDiscardedContent(
            &self,
            evicts_objects_with_discarded_content: bool,
        );
    );
}

/// Methods declared on superclass `NSObject`.
impl<KeyType: Message, ObjectType: Message> NSCache<KeyType, ObjectType> {
    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>;
    );
}

extern_protocol!(
    /// [Apple's documentation](https://developer.apple.com/documentation/foundation/nscachedelegate?language=objc)
    pub unsafe trait NSCacheDelegate: NSObjectProtocol {
        /// # Safety
        ///
        /// - `cache` generic should be of the correct type.
        /// - `obj` should be of the correct type.
        #[optional]
        #[unsafe(method(cache:willEvictObject:))]
        #[unsafe(method_family = none)]
        unsafe fn cache_willEvictObject(&self, cache: &NSCache, obj: &AnyObject);
    }
);
