// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//

public protocol URLAuthenticationChallengeSender : NSObjectProtocol {
    
    
    /*!
     @method useCredential:forAuthenticationChallenge:
     */
    func use(_ credential: URLCredential, for challenge: URLAuthenticationChallenge)
    
    
    /*!
     @method continueWithoutCredentialForAuthenticationChallenge:
     */
    func continueWithoutCredential(for challenge: URLAuthenticationChallenge)
    
    
    /*!
     @method cancelAuthenticationChallenge:
     */
    func cancel(_ challenge: URLAuthenticationChallenge)
    
    
    /*!
     @method performDefaultHandlingForAuthenticationChallenge:
     */
    func performDefaultHandling(for challenge: URLAuthenticationChallenge)
    
    
    /*!
     @method rejectProtectionSpaceAndContinueWithChallenge:
     */
    func rejectProtectionSpaceAndContinue(with challenge: URLAuthenticationChallenge)
}

/*!
    @class NSURLAuthenticationChallenge
    @discussion This class represents an authentication challenge. It
    provides all the information about the challenge, and has a method
    to indicate when it's done.
*/
open class URLAuthenticationChallenge : NSObject, NSSecureCoding {
    
    static public var supportsSecureCoding: Bool {
        return true
    }
    
    public required init?(coder aDecoder: NSCoder) {
        NSUnimplemented()
    }
    
    open func encode(with aCoder: NSCoder) {
        NSUnimplemented()
    }
    
    
    /*!
     @method initWithProtectionSpace:proposedCredential:previousFailureCount:failureResponse:error:
     @abstract Initialize an authentication challenge
     @param space The NSURLProtectionSpace to use
     @param credential The proposed NSURLCredential for this challenge, or nil
     @param previousFailureCount A count of previous failures attempting access.
     @param response The NSURLResponse for the authentication failure, if applicable, else nil
     @param error The NSError for the authentication failure, if applicable, else nil
     @result An authentication challenge initialized with the specified parameters
     */
    public init(protectionSpace space: URLProtectionSpace, proposedCredential credential: URLCredential?, previousFailureCount: Int, failureResponse response: URLResponse?, error: NSError?, sender: URLAuthenticationChallengeSender) {
        NSUnimplemented()
    }
    
    
    /*!
     @method initWithAuthenticationChallenge:
     @abstract Initialize an authentication challenge copying all parameters from another one.
     @param challenge
     @result A new challenge initialized with the parameters from the passed in challenge
     @discussion This initializer may be useful to subclassers that want to proxy
     one type of authentication challenge to look like another type.
     */
    public init(authenticationChallenge challenge: URLAuthenticationChallenge, sender: URLAuthenticationChallengeSender) {
        NSUnimplemented()
    }
    
    
    /*!
     @method protectionSpace
     @abstract Get a description of the protection space that requires authentication
     @result The protection space that needs authentication
     */
    /*@NSCopying*/ open var protectionSpace: URLProtectionSpace {
        get {
            NSUnimplemented()
        }
    }
    
    
    /*!
     @method proposedCredential
     @abstract Get the proposed credential for this challenge
     @result The proposed credential
     @discussion proposedCredential may be nil, if there is no default
     credential to use for this challenge (either stored or in the
     URL). If the credential is not nil and returns YES for
     hasPassword, this means the NSURLConnection thinks the credential
     is ready to use as-is. If it returns NO for hasPassword, then the
     credential is not ready to use as-is, but provides a default
     username the client could use when prompting.
     */
    /*@NSCopying*/ open var proposedCredential: URLCredential? {
        get {
            NSUnimplemented()
        }
    }
    
    
    /*!
     @method previousFailureCount
     @abstract Get count of previous failed authentication attempts
     @result The count of previous failures
     */
    open var previousFailureCount: Int {
        get {
            NSUnimplemented()
        }
    }
    
    
    /*!
     @method failureResponse
     @abstract Get the response representing authentication failure.
     @result The failure response or nil
     @discussion If there was a previous authentication failure, and
     this protocol uses responses to indicate authentication failure,
     then this method will return the response. Otherwise it will
     return nil.
     */
    /*@NSCopying*/ open var failureResponse: URLResponse? {
        get {
            NSUnimplemented()
        }
    }
    
    
    /*!
     @method error
     @abstract Get the error representing authentication failure.
     @discussion If there was a previous authentication failure, and
     this protocol uses errors to indicate authentication failure,
     then this method will return the error. Otherwise it will
     return nil.
     */
    /*@NSCopying*/ open var error: NSError? {
        get {
            NSUnimplemented()
        }
    }
    
    
    /*!
     @method sender
     @abstract Get the sender of this challenge
     @result The sender of the challenge
     @discussion The sender is the object you should reply to when done processing the challenge.
     */
    open var sender: URLAuthenticationChallengeSender? {
        get {
            NSUnimplemented()
        }
    }
}
