//! 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_class!(
    /// Description for a machine learning pipeline state.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4machinelearningpipelinedescriptor?language=objc)
    #[unsafe(super(MTL4PipelineDescriptor, NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    #[cfg(feature = "MTL4PipelineState")]
    pub struct MTL4MachineLearningPipelineDescriptor;
);

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

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

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

#[cfg(feature = "MTL4PipelineState")]
impl MTL4MachineLearningPipelineDescriptor {
    extern_methods!(
        /// Assigns an optional string that helps identify pipeline states you create from this descriptor.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        pub fn label(&self) -> Option<Retained<NSString>>;

        /// Setter for [`label`][Self::label].
        ///
        /// This is [copied][objc2_foundation::NSCopying::copy] when set.
        #[unsafe(method(setLabel:))]
        #[unsafe(method_family = none)]
        pub fn setLabel(&self, label: Option<&NSString>);

        #[cfg(feature = "MTL4FunctionDescriptor")]
        /// Assigns the function that the machine learning pipeline you create from this descriptor executes.
        #[unsafe(method(machineLearningFunctionDescriptor))]
        #[unsafe(method_family = none)]
        pub fn machineLearningFunctionDescriptor(&self)
            -> Option<Retained<MTL4FunctionDescriptor>>;

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

        #[cfg(feature = "MTLTensor")]
        /// Sets the dimension of an input tensor at a buffer index.
        ///
        /// - Parameters:
        /// - dimensions: the dimensions of the tensor.
        /// - bufferIndex: Index of the tensor to modify.
        ///
        /// # Safety
        ///
        /// `bufferIndex` might not be bounds-checked.
        #[unsafe(method(setInputDimensions:atBufferIndex:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setInputDimensions_atBufferIndex(
            &self,
            dimensions: Option<&MTLTensorExtents>,
            buffer_index: NSInteger,
        );

        #[cfg(feature = "MTLTensor")]
        /// Sets the dimensions of multiple input tensors on a range of buffer bindings.
        ///
        /// Use this method to specify the dimensions of multiple input tensors at a range of indices in a single call.
        ///
        /// You can indicate that any tensors in the range have unspecified dimensions by providing `NSNull` at the their
        /// corresponding index location in the array.
        ///
        /// - Important: The range's length property needs to match the number of dimensions you provide. Specifically,
        /// `range.length` needs to match `dimensions.count`.
        ///
        /// - Parameters:
        /// - dimensions: An array of tensor extents.
        /// - range: The range of inputs of the `dimensions` argument.
        /// The range's `length` needs to match the dimensions' `count` property.
        ///
        /// # Safety
        ///
        /// `range` might not be bounds-checked.
        #[unsafe(method(setInputDimensions:withRange:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setInputDimensions_withRange(
            &self,
            dimensions: &NSArray<MTLTensorExtents>,
            range: NSRange,
        );

        #[cfg(feature = "MTLTensor")]
        /// Obtains the dimensions of the input tensor at `bufferIndex` if set, `nil` otherwise.
        ///
        /// # Safety
        ///
        /// `bufferIndex` might not be bounds-checked.
        #[unsafe(method(inputDimensionsAtBufferIndex:))]
        #[unsafe(method_family = none)]
        pub unsafe fn inputDimensionsAtBufferIndex(
            &self,
            buffer_index: NSInteger,
        ) -> Option<Retained<MTLTensorExtents>>;

        /// Resets the descriptor to its default values.
        #[unsafe(method(reset))]
        #[unsafe(method_family = none)]
        pub fn reset(&self);
    );
}

/// Methods declared on superclass `NSObject`.
#[cfg(feature = "MTL4PipelineState")]
impl MTL4MachineLearningPipelineDescriptor {
    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>;
    );
}

#[cfg(feature = "MTL4PipelineState")]
impl DefaultRetained for MTL4MachineLearningPipelineDescriptor {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_class!(
    /// Represents reflection information for a machine learning pipeline state.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4machinelearningpipelinereflection?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct MTL4MachineLearningPipelineReflection;
);

unsafe impl Send for MTL4MachineLearningPipelineReflection {}

unsafe impl Sync for MTL4MachineLearningPipelineReflection {}

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

impl MTL4MachineLearningPipelineReflection {
    extern_methods!(
        #[cfg(feature = "MTLArgument")]
        /// Describes every input and output of the pipeline.
        #[unsafe(method(bindings))]
        #[unsafe(method_family = none)]
        pub fn bindings(&self) -> Retained<NSArray<ProtocolObject<dyn MTLBinding>>>;
    );
}

/// Methods declared on superclass `NSObject`.
impl MTL4MachineLearningPipelineReflection {
    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 MTL4MachineLearningPipelineReflection {
    #[inline]
    fn default_retained() -> Retained<Self> {
        Self::new()
    }
}

extern_protocol!(
    /// A pipeline state that you can use with machine-learning encoder instances.
    ///
    /// See ``MTL4MachineLearningCommandEncoder`` for more information.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/metal/mtl4machinelearningpipelinestate?language=objc)
    #[cfg(feature = "MTLAllocation")]
    pub unsafe trait MTL4MachineLearningPipelineState:
        MTLAllocation + NSObjectProtocol + Send + Sync
    {
        /// Queries the string that helps identify this object.
        #[unsafe(method(label))]
        #[unsafe(method_family = none)]
        fn label(&self) -> Option<Retained<NSString>>;

        #[cfg(feature = "MTLDevice")]
        /// Returns the device the pipeline state belongs to.
        #[unsafe(method(device))]
        #[unsafe(method_family = none)]
        fn device(&self) -> Retained<ProtocolObject<dyn MTLDevice>>;

        /// Returns reflection information for this machine learning pipeline state.
        #[unsafe(method(reflection))]
        #[unsafe(method_family = none)]
        fn reflection(&self) -> Option<Retained<MTL4MachineLearningPipelineReflection>>;

        /// Obtain the size of the heap, in bytes, this pipeline requires during the execution.
        ///
        /// Use this value to allocate a ``MTLHeap`` instance of sufficient size that you can then provide to
        /// ``MTL4MachineLearningCommandEncoder/dispatchNetworkWithIntermediatesHeap:``.
        ///
        /// Metal uses this heap to store intermediate data as it executes the pipeline. It is your responsibility to provide
        /// a heap at least as large as this property requests.
        #[unsafe(method(intermediatesHeapSize))]
        #[unsafe(method_family = none)]
        fn intermediatesHeapSize(&self) -> NSUInteger;
    }
);
