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

/// [Apple's documentation](https://developer.apple.com/documentation/foundation/nsexpressiontype?language=objc)
// NS_ENUM
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct NSExpressionType(pub NSUInteger);
impl NSExpressionType {
    #[doc(alias = "NSConstantValueExpressionType")]
    pub const ConstantValueExpressionType: Self = Self(0);
    #[doc(alias = "NSEvaluatedObjectExpressionType")]
    pub const EvaluatedObjectExpressionType: Self = Self(1);
    #[doc(alias = "NSVariableExpressionType")]
    pub const VariableExpressionType: Self = Self(2);
    #[doc(alias = "NSKeyPathExpressionType")]
    pub const KeyPathExpressionType: Self = Self(3);
    #[doc(alias = "NSFunctionExpressionType")]
    pub const FunctionExpressionType: Self = Self(4);
    #[doc(alias = "NSUnionSetExpressionType")]
    pub const UnionSetExpressionType: Self = Self(5);
    #[doc(alias = "NSIntersectSetExpressionType")]
    pub const IntersectSetExpressionType: Self = Self(6);
    #[doc(alias = "NSMinusSetExpressionType")]
    pub const MinusSetExpressionType: Self = Self(7);
    #[doc(alias = "NSSubqueryExpressionType")]
    pub const SubqueryExpressionType: Self = Self(13);
    #[doc(alias = "NSAggregateExpressionType")]
    pub const AggregateExpressionType: Self = Self(14);
    #[doc(alias = "NSAnyKeyExpressionType")]
    pub const AnyKeyExpressionType: Self = Self(15);
    #[doc(alias = "NSBlockExpressionType")]
    pub const BlockExpressionType: Self = Self(19);
    #[doc(alias = "NSConditionalExpressionType")]
    pub const ConditionalExpressionType: Self = Self(20);
}

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

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

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

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

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

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

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

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

impl NSExpression {
    extern_methods!(
        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        /// # Safety
        ///
        /// `arguments` generic should be of the correct type.
        #[unsafe(method(expressionWithFormat:argumentArray:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionWithFormat_argumentArray(
            expression_format: &NSString,
            arguments: &NSArray,
        ) -> Retained<NSExpression>;

        /// # Safety
        ///
        /// `obj` should be of the correct type.
        #[unsafe(method(expressionForConstantValue:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionForConstantValue(obj: Option<&AnyObject>)
            -> Retained<NSExpression>;

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

        #[cfg(feature = "NSString")]
        #[unsafe(method(expressionForVariable:))]
        #[unsafe(method_family = none)]
        pub fn expressionForVariable(string: &NSString) -> Retained<NSExpression>;

        #[cfg(feature = "NSString")]
        #[unsafe(method(expressionForKeyPath:))]
        #[unsafe(method_family = none)]
        pub fn expressionForKeyPath(key_path: &NSString) -> Retained<NSExpression>;

        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        /// # Safety
        ///
        /// `parameters` generic should be of the correct type.
        #[unsafe(method(expressionForFunction:arguments:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionForFunction_arguments(
            name: &NSString,
            parameters: &NSArray,
        ) -> Retained<NSExpression>;

        #[cfg(feature = "NSArray")]
        #[unsafe(method(expressionForAggregate:))]
        #[unsafe(method_family = none)]
        pub fn expressionForAggregate(
            subexpressions: &NSArray<NSExpression>,
        ) -> Retained<NSExpression>;

        #[unsafe(method(expressionForUnionSet:with:))]
        #[unsafe(method_family = none)]
        pub fn expressionForUnionSet_with(
            left: &NSExpression,
            right: &NSExpression,
        ) -> Retained<NSExpression>;

        #[unsafe(method(expressionForIntersectSet:with:))]
        #[unsafe(method_family = none)]
        pub fn expressionForIntersectSet_with(
            left: &NSExpression,
            right: &NSExpression,
        ) -> Retained<NSExpression>;

        #[unsafe(method(expressionForMinusSet:with:))]
        #[unsafe(method_family = none)]
        pub fn expressionForMinusSet_with(
            left: &NSExpression,
            right: &NSExpression,
        ) -> Retained<NSExpression>;

        #[cfg(all(feature = "NSPredicate", feature = "NSString"))]
        #[unsafe(method(expressionForSubquery:usingIteratorVariable:predicate:))]
        #[unsafe(method_family = none)]
        pub fn expressionForSubquery_usingIteratorVariable_predicate(
            expression: &NSExpression,
            variable: &NSString,
            predicate: &NSPredicate,
        ) -> Retained<NSExpression>;

        #[cfg(all(feature = "NSArray", feature = "NSString"))]
        /// # Safety
        ///
        /// `parameters` generic should be of the correct type.
        #[unsafe(method(expressionForFunction:selectorName:arguments:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionForFunction_selectorName_arguments(
            target: &NSExpression,
            name: &NSString,
            parameters: Option<&NSArray>,
        ) -> Retained<NSExpression>;

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

        #[cfg(all(feature = "NSArray", feature = "NSDictionary", feature = "block2"))]
        /// # Safety
        ///
        /// - `block` block's return must be a valid pointer.
        /// - `block` block's argument 3 generic should be of the correct type.
        #[unsafe(method(expressionForBlock:arguments:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionForBlock_arguments(
            block: &block2::DynBlock<
                dyn Fn(
                    *mut AnyObject,
                    NonNull<NSArray<NSExpression>>,
                    *mut NSMutableDictionary,
                ) -> NonNull<AnyObject>,
            >,
            arguments: Option<&NSArray<NSExpression>>,
        ) -> Retained<NSExpression>;

        #[cfg(feature = "NSPredicate")]
        #[unsafe(method(expressionForConditional:trueExpression:falseExpression:))]
        #[unsafe(method_family = none)]
        pub fn expressionForConditional_trueExpression_falseExpression(
            predicate: &NSPredicate,
            true_expression: &NSExpression,
            false_expression: &NSExpression,
        ) -> Retained<NSExpression>;

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

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

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

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

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

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

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

        #[unsafe(method(operand))]
        #[unsafe(method_family = none)]
        pub fn operand(&self) -> Retained<NSExpression>;

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

        #[unsafe(method(collection))]
        #[unsafe(method_family = none)]
        pub fn collection(&self) -> Retained<AnyObject>;

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

        #[unsafe(method(leftExpression))]
        #[unsafe(method_family = none)]
        pub fn leftExpression(&self) -> Retained<NSExpression>;

        #[unsafe(method(rightExpression))]
        #[unsafe(method_family = none)]
        pub fn rightExpression(&self) -> Retained<NSExpression>;

        #[unsafe(method(trueExpression))]
        #[unsafe(method_family = none)]
        pub fn trueExpression(&self) -> Retained<NSExpression>;

        #[unsafe(method(falseExpression))]
        #[unsafe(method_family = none)]
        pub fn falseExpression(&self) -> Retained<NSExpression>;

        #[cfg(all(feature = "NSArray", feature = "NSDictionary", feature = "block2"))]
        /// # Safety
        ///
        /// - The returned block's argument 1 must be a valid pointer or null.
        /// - The returned block's argument 2 must be a valid pointer.
        /// - The returned block's argument 3 must be a valid pointer or null.
        #[unsafe(method(expressionBlock))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionBlock(
            &self,
        ) -> NonNull<
            block2::DynBlock<
                dyn Fn(
                    *mut AnyObject,
                    NonNull<NSArray<NSExpression>>,
                    *mut NSMutableDictionary,
                ) -> NonNull<AnyObject>,
            >,
        >;

        #[cfg(feature = "NSDictionary")]
        /// # Safety
        ///
        /// - `object` should be of the correct type.
        /// - `context` generic should be of the correct type.
        #[unsafe(method(expressionValueWithObject:context:))]
        #[unsafe(method_family = none)]
        pub unsafe fn expressionValueWithObject_context(
            &self,
            object: Option<&AnyObject>,
            context: Option<&NSMutableDictionary>,
        ) -> Option<Retained<AnyObject>>;

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

/// Methods declared on superclass `NSObject`.
impl NSExpression {
    extern_methods!(
        #[unsafe(method(init))]
        #[unsafe(method_family = init)]
        pub fn init(this: Allocated<Self>) -> Retained<Self>;

        #[unsafe(method(new))]
        #[unsafe(method_family = new)]
        pub fn new() -> Retained<Self>;
    );
}

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