//! 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_protocol!(
    /// NSURLProtocolClient provides the interface to the URL
    /// loading system that is intended for use by NSURLProtocol
    /// implementors.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlprotocolclient?language=objc)
    pub unsafe trait NSURLProtocolClient: NSObjectProtocol + Send + Sync {
        #[cfg(all(feature = "NSURLRequest", feature = "NSURLResponse"))]
        /// Indicates to an NSURLProtocolClient that a redirect has
        /// occurred.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        ///
        /// Parameter `request`: the NSURLRequest to which the protocol implementation
        /// has redirected.
        #[unsafe(method(URLProtocol:wasRedirectedToRequest:redirectResponse:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_wasRedirectedToRequest_redirectResponse(
            &self,
            protocol: &NSURLProtocol,
            request: &NSURLRequest,
            redirect_response: &NSURLResponse,
        );

        #[cfg(feature = "NSURLCache")]
        /// Indicates to an NSURLProtocolClient that the protocol
        /// implementation has examined a cached response and has
        /// determined that it is valid.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        ///
        /// Parameter `cachedResponse`: the NSCachedURLResponse object that has
        /// examined and is valid.
        #[unsafe(method(URLProtocol:cachedResponseIsValid:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_cachedResponseIsValid(
            &self,
            protocol: &NSURLProtocol,
            cached_response: &NSCachedURLResponse,
        );

        #[cfg(all(feature = "NSURLCache", feature = "NSURLResponse"))]
        /// Indicates to an NSURLProtocolClient that the protocol
        /// implementation has created an NSURLResponse for the current load.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        ///
        /// Parameter `response`: the NSURLResponse object the protocol implementation
        /// has created.
        ///
        /// Parameter `policy`: The NSURLCacheStoragePolicy the protocol
        /// has determined should be used for the given response if the
        /// response is to be stored in a cache.
        #[unsafe(method(URLProtocol:didReceiveResponse:cacheStoragePolicy:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_didReceiveResponse_cacheStoragePolicy(
            &self,
            protocol: &NSURLProtocol,
            response: &NSURLResponse,
            policy: NSURLCacheStoragePolicy,
        );

        #[cfg(feature = "NSData")]
        /// Indicates to an NSURLProtocolClient that the protocol
        /// implementation has loaded URL data.
        ///
        /// The data object must contain only new data loaded since
        /// the previous call to this method (if any), not cumulative data for
        /// the entire load.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        ///
        /// Parameter `data`: URL load data being made available.
        #[unsafe(method(URLProtocol:didLoadData:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_didLoadData(&self, protocol: &NSURLProtocol, data: &NSData);

        /// Indicates to an NSURLProtocolClient that the protocol
        /// implementation has finished loading successfully.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        #[unsafe(method(URLProtocolDidFinishLoading:))]
        #[unsafe(method_family = none)]
        fn URLProtocolDidFinishLoading(&self, protocol: &NSURLProtocol);

        #[cfg(feature = "NSError")]
        /// Indicates to an NSURLProtocolClient that the protocol
        /// implementation has failed to load successfully.
        ///
        /// Parameter `protocol`: the NSURLProtocol object sending the message.
        ///
        /// Parameter `error`: The error that caused the load to fail.
        #[unsafe(method(URLProtocol:didFailWithError:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_didFailWithError(&self, protocol: &NSURLProtocol, error: &NSError);

        #[cfg(feature = "NSURLAuthenticationChallenge")]
        /// Start authentication for the specified request
        ///
        /// Parameter `protocol`: The protocol object requesting authentication.
        ///
        /// Parameter `challenge`: The authentication challenge.
        ///
        /// The protocol client guarantees that it will answer the
        /// request on the same thread that called this method. It may add a
        /// default credential to the challenge it issues to the connection delegate,
        /// if the protocol did not provide one.
        #[unsafe(method(URLProtocol:didReceiveAuthenticationChallenge:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_didReceiveAuthenticationChallenge(
            &self,
            protocol: &NSURLProtocol,
            challenge: &NSURLAuthenticationChallenge,
        );

        #[cfg(feature = "NSURLAuthenticationChallenge")]
        /// Cancel authentication for the specified request
        ///
        /// Parameter `protocol`: The protocol object cancelling authentication.
        ///
        /// Parameter `challenge`: The authentication challenge.
        #[unsafe(method(URLProtocol:didCancelAuthenticationChallenge:))]
        #[unsafe(method_family = none)]
        fn URLProtocol_didCancelAuthenticationChallenge(
            &self,
            protocol: &NSURLProtocol,
            challenge: &NSURLAuthenticationChallenge,
        );
    }
);

extern_class!(
    /// NSURLProtocol is an abstract class which provides the
    /// basic structure for performing protocol-specific loading of URL
    /// data. Concrete subclasses handle the specifics associated with one
    /// or more protocols or URL schemes.
    ///
    /// See also [Apple's documentation](https://developer.apple.com/documentation/foundation/nsurlprotocol?language=objc)
    #[unsafe(super(NSObject))]
    #[derive(Debug, PartialEq, Eq, Hash)]
    pub struct NSURLProtocol;
);

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

impl NSURLProtocol {
    extern_methods!(
        #[cfg(all(feature = "NSURLCache", feature = "NSURLRequest"))]
        /// Initializes an NSURLProtocol given request,
        /// cached response, and client.
        ///
        /// Parameter `request`: The request to load.
        ///
        /// Parameter `cachedResponse`: A response that has been retrieved from the
        /// cache for the given request. The protocol implementation should
        /// apply protocol-specific validity checks if such tests are
        /// necessary.
        ///
        /// Parameter `client`: The NSURLProtocolClient object that serves as the
        /// interface the protocol implementation can use to report results back
        /// to the URL loading system.
        #[unsafe(method(initWithRequest:cachedResponse:client:))]
        #[unsafe(method_family = init)]
        pub fn initWithRequest_cachedResponse_client(
            this: Allocated<Self>,
            request: &NSURLRequest,
            cached_response: Option<&NSCachedURLResponse>,
            client: Option<&ProtocolObject<dyn NSURLProtocolClient>>,
        ) -> Retained<Self>;

        /// Returns the NSURLProtocolClient of the receiver.
        ///
        /// Returns: The NSURLProtocolClient of the receiver.
        #[unsafe(method(client))]
        #[unsafe(method_family = none)]
        pub fn client(&self) -> Option<Retained<ProtocolObject<dyn NSURLProtocolClient>>>;

        #[cfg(feature = "NSURLRequest")]
        /// Returns the NSURLRequest of the receiver.
        ///
        /// Returns: The NSURLRequest of the receiver.
        #[unsafe(method(request))]
        #[unsafe(method_family = none)]
        pub fn request(&self) -> Retained<NSURLRequest>;

        #[cfg(feature = "NSURLCache")]
        /// Returns the NSCachedURLResponse of the receiver.
        ///
        /// Returns: The NSCachedURLResponse of the receiver.
        #[unsafe(method(cachedResponse))]
        #[unsafe(method_family = none)]
        pub fn cachedResponse(&self) -> Option<Retained<NSCachedURLResponse>>;

        #[cfg(feature = "NSURLRequest")]
        /// This method determines whether this protocol can handle
        /// the given request.
        ///
        /// A concrete subclass should inspect the given request and
        /// determine whether or not the implementation can perform a load with
        /// that request. This is an abstract method. Subclasses must provide an
        /// implementation.
        ///
        /// Parameter `request`: A request to inspect.
        ///
        /// Returns: YES if the protocol can handle the given request, NO if not.
        #[unsafe(method(canInitWithRequest:))]
        #[unsafe(method_family = none)]
        pub fn canInitWithRequest(request: &NSURLRequest) -> bool;

        #[cfg(feature = "NSURLRequest")]
        /// This method returns a canonical version of the given
        /// request.
        ///
        /// It is up to each concrete protocol implementation to
        /// define what "canonical" means. However, a protocol should
        /// guarantee that the same input request always yields the same
        /// canonical form. Special consideration should be given when
        /// implementing this method since the canonical form of a request is
        /// used to look up objects in the URL cache, a process which performs
        /// equality checks between NSURLRequest objects.
        /// <p>
        /// This is an abstract method; subclasses must provide an
        /// implementation.
        ///
        /// Parameter `request`: A request to make canonical.
        ///
        /// Returns: The canonical form of the given request.
        #[unsafe(method(canonicalRequestForRequest:))]
        #[unsafe(method_family = none)]
        pub fn canonicalRequestForRequest(request: &NSURLRequest) -> Retained<NSURLRequest>;

        #[cfg(feature = "NSURLRequest")]
        /// Compares two requests for equivalence with regard to caching.
        ///
        /// Requests are considered equivalent for cache purposes
        /// if and only if they would be handled by the same protocol AND that
        /// protocol declares them equivalent after performing
        /// implementation-specific checks.
        ///
        /// Returns: YES if the two requests are cache-equivalent, NO otherwise.
        #[unsafe(method(requestIsCacheEquivalent:toRequest:))]
        #[unsafe(method_family = none)]
        pub fn requestIsCacheEquivalent_toRequest(a: &NSURLRequest, b: &NSURLRequest) -> bool;

        /// Starts protocol-specific loading of a request.
        ///
        /// When this method is called, the protocol implementation
        /// should start loading a request.
        #[unsafe(method(startLoading))]
        #[unsafe(method_family = none)]
        pub fn startLoading(&self);

        /// Stops protocol-specific loading of a request.
        ///
        /// When this method is called, the protocol implementation
        /// should end the work of loading a request. This could be in response
        /// to a cancel operation, so protocol implementations must be able to
        /// handle this call while a load is in progress.
        #[unsafe(method(stopLoading))]
        #[unsafe(method_family = none)]
        pub fn stopLoading(&self);

        #[cfg(all(feature = "NSString", feature = "NSURLRequest"))]
        /// Returns the property in the given request previously
        /// stored with the given key.
        ///
        /// The purpose of this method is to provide an interface
        /// for protocol implementors to access protocol-specific information
        /// associated with NSURLRequest objects.
        ///
        /// Parameter `key`: The string to use for the property lookup.
        ///
        /// Parameter `request`: The request to use for the property lookup.
        ///
        /// Returns: The property stored with the given key, or nil if no property
        /// had previously been stored with the given key in the given request.
        #[unsafe(method(propertyForKey:inRequest:))]
        #[unsafe(method_family = none)]
        pub fn propertyForKey_inRequest(
            key: &NSString,
            request: &NSURLRequest,
        ) -> Option<Retained<AnyObject>>;

        #[cfg(all(feature = "NSString", feature = "NSURLRequest"))]
        /// Stores the given property in the given request using the
        /// given key.
        ///
        /// The purpose of this method is to provide an interface
        /// for protocol implementors to customize protocol-specific
        /// information associated with NSMutableURLRequest objects.
        ///
        /// Parameter `value`: The property to store.
        ///
        /// Parameter `key`: The string to use for the property storage.
        ///
        /// Parameter `request`: The request in which to store the property.
        ///
        /// # Safety
        ///
        /// `value` should be of the correct type.
        #[unsafe(method(setProperty:forKey:inRequest:))]
        #[unsafe(method_family = none)]
        pub unsafe fn setProperty_forKey_inRequest(
            value: &AnyObject,
            key: &NSString,
            request: &NSMutableURLRequest,
        );

        #[cfg(all(feature = "NSString", feature = "NSURLRequest"))]
        /// Remove any property stored under the given key
        ///
        /// Like setProperty:forKey:inRequest: above, the purpose of this
        /// method is to give protocol implementors the ability to store
        /// protocol-specific information in an NSURLRequest
        ///
        /// Parameter `key`: The key whose value should be removed
        ///
        /// Parameter `request`: The request to be modified
        #[unsafe(method(removePropertyForKey:inRequest:))]
        #[unsafe(method_family = none)]
        pub fn removePropertyForKey_inRequest(key: &NSString, request: &NSMutableURLRequest);

        /// This method registers a protocol class, making it visible
        /// to several other NSURLProtocol class methods.
        ///
        /// When the URL loading system begins to load a request,
        /// each protocol class that has been registered is consulted in turn to
        /// see if it can be initialized with a given request. The first
        /// protocol handler class to provide a YES answer to
        /// <tt>
        /// +canInitWithRequest:
        /// </tt>
        /// "wins" and that protocol
        /// implementation is used to perform the URL load. There is no
        /// guarantee that all registered protocol classes will be consulted.
        /// Hence, it should be noted that registering a class places it first
        /// on the list of classes that will be consulted in calls to
        /// <tt>
        /// +canInitWithRequest:
        /// </tt>
        /// , moving it in front of all classes
        /// that had been registered previously.
        /// <p>
        /// A similar design governs the process to create the canonical form
        /// of a request with the
        /// <tt>
        /// +canonicalRequestForRequest:
        /// </tt>
        /// class
        /// method.
        ///
        /// Parameter `protocolClass`: the class to register.
        ///
        /// Returns: YES if the protocol was registered successfully, NO if not.
        /// The only way that failure can occur is if the given class is not a
        /// subclass of NSURLProtocol.
        ///
        /// # Safety
        ///
        /// `protocol_class` probably has further requirements.
        #[unsafe(method(registerClass:))]
        #[unsafe(method_family = none)]
        pub unsafe fn registerClass(protocol_class: &AnyClass) -> bool;

        /// This method unregisters a protocol.
        ///
        /// After unregistration, a protocol class is no longer
        /// consulted in calls to NSURLProtocol class methods.
        ///
        /// Parameter `protocolClass`: The class to unregister.
        ///
        /// # Safety
        ///
        /// `protocol_class` probably has further requirements.
        #[unsafe(method(unregisterClass:))]
        #[unsafe(method_family = none)]
        pub unsafe fn unregisterClass(protocol_class: &AnyClass);
    );
}

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

/// NSURLSessionTaskAdditions.
impl NSURLProtocol {
    extern_methods!(
        #[cfg(feature = "NSURLSession")]
        #[unsafe(method(canInitWithTask:))]
        #[unsafe(method_family = none)]
        pub fn canInitWithTask(task: &NSURLSessionTask) -> bool;

        #[cfg(all(feature = "NSURLCache", feature = "NSURLSession"))]
        #[unsafe(method(initWithTask:cachedResponse:client:))]
        #[unsafe(method_family = init)]
        pub fn initWithTask_cachedResponse_client(
            this: Allocated<Self>,
            task: &NSURLSessionTask,
            cached_response: Option<&NSCachedURLResponse>,
            client: Option<&ProtocolObject<dyn NSURLProtocolClient>>,
        ) -> Retained<Self>;

        #[cfg(feature = "NSURLSession")]
        #[unsafe(method(task))]
        #[unsafe(method_family = none)]
        pub fn task(&self) -> Option<Retained<NSURLSessionTask>>;
    );
}
