// Manager.swift
//
// Copyright (c) 2014–2016 Alamofire Software Foundation (http://alamofire.org/)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

import Foundation

/**
    Responsible for creating and managing `Request` objects, as well as their underlying `NSURLSession`.
*/
public class Manager {

    // MARK: - Properties

    /**
        A shared instance of `Manager`, used by top-level Alamofire request methods, and suitable for use directly 
        for any ad hoc requests.
    */
    public static let sharedInstance: Manager = {
        let configuration = NSURLSessionConfiguration.defaultSessionConfiguration()
        configuration.HTTPAdditionalHeaders = Manager.defaultHTTPHeaders

        return Manager(configuration: configuration)
    }()

    /**
        Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
    */
    public static let defaultHTTPHeaders: [String: String] = {
        // Accept-Encoding HTTP Header; see https://tools.ietf.org/html/rfc7230#section-4.2.3
        let acceptEncoding: String = "gzip;q=1.0, compress;q=0.5"

        // Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
        let acceptLanguage = NSLocale.preferredLanguages().prefix(6).enumerate().map { index, languageCode in
            let quality = 1.0 - (Double(index) * 0.1)
            return "\(languageCode);q=\(quality)"
        }.joinWithSeparator(", ")

        // User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
        let userAgent: String = {
            if let info = NSBundle.mainBundle().infoDictionary {
                let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown"
                let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown"
                let version = info[kCFBundleVersionKey as String] as? String ?? "Unknown"
                let os = NSProcessInfo.processInfo().operatingSystemVersionString

                var mutableUserAgent = NSMutableString(string: "\(executable)/\(bundle) (\(version); OS \(os))") as CFMutableString
                let transform = NSString(string: "Any-Latin; Latin-ASCII; [:^ASCII:] Remove") as CFString

                if CFStringTransform(mutableUserAgent, UnsafeMutablePointer<CFRange>(nil), transform, false) {
                    return mutableUserAgent as String
                }
            }

            return "Alamofire"
        }()

        return [
            "Accept-Encoding": acceptEncoding,
            "Accept-Language": acceptLanguage,
            "User-Agent": userAgent
        ]
    }()

    let queue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL)

    /// The underlying session.
    public let session: NSURLSession

    /// The session delegate handling all the task and session delegate callbacks.
    public let delegate: SessionDelegate

    /// Whether to start requests immediately after being constructed. `true` by default.
    public var startRequestsImmediately: Bool = true

    /**
        The background completion handler closure provided by the UIApplicationDelegate 
        `application:handleEventsForBackgroundURLSession:completionHandler:` method. By setting the background 
        completion handler, the SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` closure implementation 
        will automatically call the handler.
    
        If you need to handle your own events before the handler is called, then you need to override the 
        SessionDelegate `sessionDidFinishEventsForBackgroundURLSession` and manually call the handler when finished.
    
        `nil` by default.
    */
    public var backgroundCompletionHandler: (() -> Void)?

    // MARK: - Lifecycle

    /**
        Initializes the `Manager` instance with the specified configuration, delegate and server trust policy.

        - parameter configuration:            The configuration used to construct the managed session. 
                                              `NSURLSessionConfiguration.defaultSessionConfiguration()` by default.
        - parameter delegate:                 The delegate used when initializing the session. `SessionDelegate()` by
                                              default.
        - parameter serverTrustPolicyManager: The server trust policy manager to use for evaluating all server trust 
                                              challenges. `nil` by default.

        - returns: The new `Manager` instance.
    */
    public init(
        configuration: NSURLSessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration(),
        delegate: SessionDelegate = SessionDelegate(),
        serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
    {
        self.delegate = delegate
        self.session = NSURLSession(configuration: configuration, delegate: delegate, delegateQueue: nil)

        commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
    }

    /**
        Initializes the `Manager` instance with the specified session, delegate and server trust policy.

        - parameter session:                  The URL session.
        - parameter delegate:                 The delegate of the URL session. Must equal the URL session's delegate.
        - parameter serverTrustPolicyManager: The server trust policy manager to use for evaluating all server trust
                                              challenges. `nil` by default.

        - returns: The new `Manager` instance if the URL session's delegate matches the delegate parameter.
    */
    public init?(
        session: NSURLSession,
        delegate: SessionDelegate,
        serverTrustPolicyManager: ServerTrustPolicyManager? = nil)
    {
        self.delegate = delegate
        self.session = session

        guard delegate === session.delegate else { return nil }

        commonInit(serverTrustPolicyManager: serverTrustPolicyManager)
    }

    private func commonInit(serverTrustPolicyManager serverTrustPolicyManager: ServerTrustPolicyManager?) {
        session.serverTrustPolicyManager = serverTrustPolicyManager

        delegate.sessionDidFinishEventsForBackgroundURLSession = { [weak self] session in
            guard let strongSelf = self else { return }
            dispatch_async(dispatch_get_main_queue()) { strongSelf.backgroundCompletionHandler?() }
        }
    }

    deinit {
        session.invalidateAndCancel()
    }

    // MARK: - Request

    /**
        Creates a request for the specified method, URL string, parameters, parameter encoding and headers.

        - parameter method:     The HTTP method.
        - parameter URLString:  The URL string.
        - parameter parameters: The parameters. `nil` by default.
        - parameter encoding:   The parameter encoding. `.URL` by default.
        - parameter headers:    The HTTP headers. `nil` by default.

        - returns: The created request.
    */
    public func request(
        method: Method,
        _ URLString: URLStringConvertible,
        parameters: [String: AnyObject]? = nil,
        encoding: ParameterEncoding = .URL,
        headers: [String: String]? = nil)
        -> Request
    {
        let mutableURLRequest = URLRequest(method, URLString, headers: headers)
        let encodedURLRequest = encoding.encode(mutableURLRequest, parameters: parameters).0
        return request(encodedURLRequest)
    }

    /**
        Creates a request for the specified URL request.

        If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.

        - parameter URLRequest: The URL request

        - returns: The created request.
    */
    public func request(URLRequest: URLRequestConvertible) -> Request {
        var dataTask: NSURLSessionDataTask!
        dispatch_sync(queue) { dataTask = self.session.dataTaskWithRequest(URLRequest.URLRequest) }

        let request = Request(session: session, task: dataTask)
        delegate[request.delegate.task] = request.delegate

        if startRequestsImmediately {
            request.resume()
        }

        return request
    }

    // MARK: - SessionDelegate

    /**
        Responsible for handling all delegate callbacks for the underlying session.
    */
    public final class SessionDelegate: NSObject, NSURLSessionDelegate, NSURLSessionTaskDelegate, NSURLSessionDataDelegate, NSURLSessionDownloadDelegate {
        private var subdelegates: [Int: Request.TaskDelegate] = [:]
        private let subdelegateQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT)

        subscript(task: NSURLSessionTask) -> Request.TaskDelegate? {
            get {
                var subdelegate: Request.TaskDelegate?
                dispatch_sync(subdelegateQueue) { subdelegate = self.subdelegates[task.taskIdentifier] }

                return subdelegate
            }

            set {
                dispatch_barrier_async(subdelegateQueue) { self.subdelegates[task.taskIdentifier] = newValue }
            }
        }

        /**
            Initializes the `SessionDelegate` instance.

            - returns: The new `SessionDelegate` instance.
        */
        public override init() {
            super.init()
        }

        // MARK: - NSURLSessionDelegate

        // MARK: Override Closures

        /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didBecomeInvalidWithError:`.
        public var sessionDidBecomeInvalidWithError: ((NSURLSession, NSError?) -> Void)?

        /// Overrides default behavior for NSURLSessionDelegate method `URLSession:didReceiveChallenge:completionHandler:`.
        public var sessionDidReceiveChallenge: ((NSURLSession, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?

        /// Overrides all behavior for NSURLSessionDelegate method `URLSession:didReceiveChallenge:completionHandler:` and requires the caller to call the `completionHandler`.
        public var sessionDidReceiveChallengeWithCompletion: ((NSURLSession, NSURLAuthenticationChallenge, (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) -> Void)?

        /// Overrides default behavior for NSURLSessionDelegate method `URLSessionDidFinishEventsForBackgroundURLSession:`.
        public var sessionDidFinishEventsForBackgroundURLSession: ((NSURLSession) -> Void)?

        // MARK: Delegate Methods

        /**
            Tells the delegate that the session has been invalidated.

            - parameter session: The session object that was invalidated.
            - parameter error:   The error that caused invalidation, or nil if the invalidation was explicit.
        */
        public func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) {
            sessionDidBecomeInvalidWithError?(session, error)
        }

        /**
            Requests credentials from the delegate in response to a session-level authentication request from the remote server.

            - parameter session:           The session containing the task that requested authentication.
            - parameter challenge:         An object that contains the request for authentication.
            - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
        */
        public func URLSession(
            session: NSURLSession,
            didReceiveChallenge challenge: NSURLAuthenticationChallenge,
            completionHandler: ((NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void))
        {
            guard sessionDidReceiveChallengeWithCompletion == nil else {
                sessionDidReceiveChallengeWithCompletion?(session, challenge, completionHandler)
                return
            }

            var disposition: NSURLSessionAuthChallengeDisposition = .PerformDefaultHandling
            var credential: NSURLCredential?

            if let sessionDidReceiveChallenge = sessionDidReceiveChallenge {
                (disposition, credential) = sessionDidReceiveChallenge(session, challenge)
            } else if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
                let host = challenge.protectionSpace.host

                if let
                    serverTrustPolicy = session.serverTrustPolicyManager?.serverTrustPolicyForHost(host),
                    serverTrust = challenge.protectionSpace.serverTrust
                {
                    if serverTrustPolicy.evaluateServerTrust(serverTrust, isValidForHost: host) {
                        disposition = .UseCredential
                        credential = NSURLCredential(forTrust: serverTrust)
                    } else {
                        disposition = .CancelAuthenticationChallenge
                    }
                }
            }

            completionHandler(disposition, credential)
        }

        /**
            Tells the delegate that all messages enqueued for a session have been delivered.

            - parameter session: The session that no longer has any outstanding requests.
        */
        public func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) {
            sessionDidFinishEventsForBackgroundURLSession?(session)
        }

        // MARK: - NSURLSessionTaskDelegate

        // MARK: Override Closures

        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:`.
        public var taskWillPerformHTTPRedirection: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest) -> NSURLRequest?)?

        /// Overrides all behavior for NSURLSessionTaskDelegate method `URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:` and
        /// requires the caller to call the `completionHandler`.
        public var taskWillPerformHTTPRedirectionWithCompletion: ((NSURLSession, NSURLSessionTask, NSHTTPURLResponse, NSURLRequest, NSURLRequest? -> Void) -> Void)?

        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didReceiveChallenge:completionHandler:`.
        public var taskDidReceiveChallenge: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge) -> (NSURLSessionAuthChallengeDisposition, NSURLCredential?))?

        /// Overrides all behavior for NSURLSessionTaskDelegate method `URLSession:task:didReceiveChallenge:completionHandler:` and 
        /// requires the caller to call the `completionHandler`.
        public var taskDidReceiveChallengeWithCompletion: ((NSURLSession, NSURLSessionTask, NSURLAuthenticationChallenge, (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) -> Void)?

        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:session:task:needNewBodyStream:`.
        public var taskNeedNewBodyStream: ((NSURLSession, NSURLSessionTask) -> NSInputStream?)?

        /// Overrides all behavior for NSURLSessionTaskDelegate method `URLSession:session:task:needNewBodyStream:` and 
        /// requires the caller to call the `completionHandler`.
        public var taskNeedNewBodyStreamWithCompletion: ((NSURLSession, NSURLSessionTask, NSInputStream? -> Void) -> Void)?

        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`.
        public var taskDidSendBodyData: ((NSURLSession, NSURLSessionTask, Int64, Int64, Int64) -> Void)?

        /// Overrides default behavior for NSURLSessionTaskDelegate method `URLSession:task:didCompleteWithError:`.
        public var taskDidComplete: ((NSURLSession, NSURLSessionTask, NSError?) -> Void)?

        // MARK: Delegate Methods

        /**
            Tells the delegate that the remote server requested an HTTP redirect.

            - parameter session:           The session containing the task whose request resulted in a redirect.
            - parameter task:              The task whose request resulted in a redirect.
            - parameter response:          An object containing the server’s response to the original request.
            - parameter request:           A URL request object filled out with the new location.
            - parameter completionHandler: A closure that your handler should call with either the value of the request 
                                           parameter, a modified URL request object, or NULL to refuse the redirect and 
                                           return the body of the redirect response.
        */
        public func URLSession(
            session: NSURLSession,
            task: NSURLSessionTask,
            willPerformHTTPRedirection response: NSHTTPURLResponse,
            newRequest request: NSURLRequest,
            completionHandler: NSURLRequest? -> Void)
        {
            guard taskWillPerformHTTPRedirectionWithCompletion == nil else {
                taskWillPerformHTTPRedirectionWithCompletion?(session, task, response, request, completionHandler)
                return
            }

            var redirectRequest: NSURLRequest? = request

            if let taskWillPerformHTTPRedirection = taskWillPerformHTTPRedirection {
                redirectRequest = taskWillPerformHTTPRedirection(session, task, response, request)
            }

            completionHandler(redirectRequest)
        }

        /**
            Requests credentials from the delegate in response to an authentication request from the remote server.

            - parameter session:           The session containing the task whose request requires authentication.
            - parameter task:              The task whose request requires authentication.
            - parameter challenge:         An object that contains the request for authentication.
            - parameter completionHandler: A handler that your delegate method must call providing the disposition and credential.
        */
        public func URLSession(
            session: NSURLSession,
            task: NSURLSessionTask,
            didReceiveChallenge challenge: NSURLAuthenticationChallenge,
            completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void)
        {
            guard taskDidReceiveChallengeWithCompletion == nil else {
                taskDidReceiveChallengeWithCompletion?(session, task, challenge, completionHandler)
                return
            }

            if let taskDidReceiveChallenge = taskDidReceiveChallenge {
                let result = taskDidReceiveChallenge(session, task, challenge)
                completionHandler(result.0, result.1)
            } else if let delegate = self[task] {
                delegate.URLSession(
                    session,
                    task: task,
                    didReceiveChallenge: challenge,
                    completionHandler: completionHandler
                )
            } else {
                URLSession(session, didReceiveChallenge: challenge, completionHandler: completionHandler)
            }
        }

        /**
            Tells the delegate when a task requires a new request body stream to send to the remote server.

            - parameter session:           The session containing the task that needs a new body stream.
            - parameter task:              The task that needs a new body stream.
            - parameter completionHandler: A completion handler that your delegate method should call with the new body stream.
        */
        public func URLSession(
            session: NSURLSession,
            task: NSURLSessionTask,
            needNewBodyStream completionHandler: NSInputStream? -> Void)
        {
            guard taskNeedNewBodyStreamWithCompletion == nil else {
                taskNeedNewBodyStreamWithCompletion?(session, task, completionHandler)
                return
            }

            if let taskNeedNewBodyStream = taskNeedNewBodyStream {
                completionHandler(taskNeedNewBodyStream(session, task))
            } else if let delegate = self[task] {
                delegate.URLSession(session, task: task, needNewBodyStream: completionHandler)
            }
        }

        /**
            Periodically informs the delegate of the progress of sending body content to the server.

            - parameter session:                  The session containing the data task.
            - parameter task:                     The data task.
            - parameter bytesSent:                The number of bytes sent since the last time this delegate method was called.
            - parameter totalBytesSent:           The total number of bytes sent so far.
            - parameter totalBytesExpectedToSend: The expected length of the body data.
        */
        public func URLSession(
            session: NSURLSession,
            task: NSURLSessionTask,
            didSendBodyData bytesSent: Int64,
            totalBytesSent: Int64,
            totalBytesExpectedToSend: Int64)
        {
            if let taskDidSendBodyData = taskDidSendBodyData {
                taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalBytesExpectedToSend)
            } else if let delegate = self[task] as? Request.UploadTaskDelegate {
                delegate.URLSession(
                    session,
                    task: task,
                    didSendBodyData: bytesSent,
                    totalBytesSent: totalBytesSent,
                    totalBytesExpectedToSend: totalBytesExpectedToSend
                )
            }
        }

        /**
            Tells the delegate that the task finished transferring data.

            - parameter session: The session containing the task whose request finished transferring data.
            - parameter task:    The task whose request finished transferring data.
            - parameter error:   If an error occurred, an error object indicating how the transfer failed, otherwise nil.
        */
        public func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
            if let taskDidComplete = taskDidComplete {
                taskDidComplete(session, task, error)
            } else if let delegate = self[task] {
                delegate.URLSession(session, task: task, didCompleteWithError: error)
            }

            NSNotificationCenter.defaultCenter().postNotificationName(Notifications.Task.DidComplete, object: task)

            self[task] = nil
        }

        // MARK: - NSURLSessionDataDelegate

        // MARK: Override Closures

        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveResponse:completionHandler:`.
        public var dataTaskDidReceiveResponse: ((NSURLSession, NSURLSessionDataTask, NSURLResponse) -> NSURLSessionResponseDisposition)?

        /// Overrides all behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveResponse:completionHandler:` and 
        /// requires caller to call the `completionHandler`.
        public var dataTaskDidReceiveResponseWithCompletion: ((NSURLSession, NSURLSessionDataTask, NSURLResponse, NSURLSessionResponseDisposition -> Void) -> Void)?

        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didBecomeDownloadTask:`.
        public var dataTaskDidBecomeDownloadTask: ((NSURLSession, NSURLSessionDataTask, NSURLSessionDownloadTask) -> Void)?

        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:didReceiveData:`.
        public var dataTaskDidReceiveData: ((NSURLSession, NSURLSessionDataTask, NSData) -> Void)?

        /// Overrides default behavior for NSURLSessionDataDelegate method `URLSession:dataTask:willCacheResponse:completionHandler:`.
        public var dataTaskWillCacheResponse: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse) -> NSCachedURLResponse?)?

        /// Overrides all behavior for NSURLSessionDataDelegate method `URLSession:dataTask:willCacheResponse:completionHandler:` and 
        /// requires caller to call the `completionHandler`.
        public var dataTaskWillCacheResponseWithCompletion: ((NSURLSession, NSURLSessionDataTask, NSCachedURLResponse, NSCachedURLResponse? -> Void) -> Void)?

        // MARK: Delegate Methods

        /**
            Tells the delegate that the data task received the initial reply (headers) from the server.

            - parameter session:           The session containing the data task that received an initial reply.
            - parameter dataTask:          The data task that received an initial reply.
            - parameter response:          A URL response object populated with headers.
            - parameter completionHandler: A completion handler that your code calls to continue the transfer, passing a 
                                           constant to indicate whether the transfer should continue as a data task or 
                                           should become a download task.
        */
        public func URLSession(
            session: NSURLSession,
            dataTask: NSURLSessionDataTask,
            didReceiveResponse response: NSURLResponse,
            completionHandler: NSURLSessionResponseDisposition -> Void)
        {
            guard dataTaskDidReceiveResponseWithCompletion == nil else {
                dataTaskDidReceiveResponseWithCompletion?(session, dataTask, response, completionHandler)
                return
            }

            var disposition: NSURLSessionResponseDisposition = .Allow

            if let dataTaskDidReceiveResponse = dataTaskDidReceiveResponse {
                disposition = dataTaskDidReceiveResponse(session, dataTask, response)
            }

            completionHandler(disposition)
        }

        /**
            Tells the delegate that the data task was changed to a download task.

            - parameter session:      The session containing the task that was replaced by a download task.
            - parameter dataTask:     The data task that was replaced by a download task.
            - parameter downloadTask: The new download task that replaced the data task.
        */
        public func URLSession(
            session: NSURLSession,
            dataTask: NSURLSessionDataTask,
            didBecomeDownloadTask downloadTask: NSURLSessionDownloadTask)
        {
            if let dataTaskDidBecomeDownloadTask = dataTaskDidBecomeDownloadTask {
                dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask)
            } else {
                let downloadDelegate = Request.DownloadTaskDelegate(task: downloadTask)
                self[downloadTask] = downloadDelegate
            }
        }

        /**
            Tells the delegate that the data task has received some of the expected data.

            - parameter session:  The session containing the data task that provided data.
            - parameter dataTask: The data task that provided data.
            - parameter data:     A data object containing the transferred data.
        */
        public func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
            if let dataTaskDidReceiveData = dataTaskDidReceiveData {
                dataTaskDidReceiveData(session, dataTask, data)
            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
                delegate.URLSession(session, dataTask: dataTask, didReceiveData: data)
            }
        }

        /**
            Asks the delegate whether the data (or upload) task should store the response in the cache.

            - parameter session:           The session containing the data (or upload) task.
            - parameter dataTask:          The data (or upload) task.
            - parameter proposedResponse:  The default caching behavior. This behavior is determined based on the current 
                                           caching policy and the values of certain received headers, such as the Pragma 
                                           and Cache-Control headers.
            - parameter completionHandler: A block that your handler must call, providing either the original proposed 
                                           response, a modified version of that response, or NULL to prevent caching the 
                                           response. If your delegate implements this method, it must call this completion 
                                           handler; otherwise, your app leaks memory.
        */
        public func URLSession(
            session: NSURLSession,
            dataTask: NSURLSessionDataTask,
            willCacheResponse proposedResponse: NSCachedURLResponse,
            completionHandler: NSCachedURLResponse? -> Void)
        {
            guard dataTaskWillCacheResponseWithCompletion == nil else {
                dataTaskWillCacheResponseWithCompletion?(session, dataTask, proposedResponse, completionHandler)
                return
            }

            if let dataTaskWillCacheResponse = dataTaskWillCacheResponse {
                completionHandler(dataTaskWillCacheResponse(session, dataTask, proposedResponse))
            } else if let delegate = self[dataTask] as? Request.DataTaskDelegate {
                delegate.URLSession(
                    session,
                    dataTask: dataTask,
                    willCacheResponse: proposedResponse,
                    completionHandler: completionHandler
                )
            } else {
                completionHandler(proposedResponse)
            }
        }

        // MARK: - NSURLSessionDownloadDelegate

        // MARK: Override Closures

        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didFinishDownloadingToURL:`.
        public var downloadTaskDidFinishDownloadingToURL: ((NSURLSession, NSURLSessionDownloadTask, NSURL) -> Void)?

        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:`.
        public var downloadTaskDidWriteData: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64, Int64) -> Void)?

        /// Overrides default behavior for NSURLSessionDownloadDelegate method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`.
        public var downloadTaskDidResumeAtOffset: ((NSURLSession, NSURLSessionDownloadTask, Int64, Int64) -> Void)?

        // MARK: Delegate Methods

        /**
            Tells the delegate that a download task has finished downloading.

            - parameter session:      The session containing the download task that finished.
            - parameter downloadTask: The download task that finished.
            - parameter location:     A file URL for the temporary file. Because the file is temporary, you must either 
                                      open the file for reading or move it to a permanent location in your app’s sandbox 
                                      container directory before returning from this delegate method.
        */
        public func URLSession(
            session: NSURLSession,
            downloadTask: NSURLSessionDownloadTask,
            didFinishDownloadingToURL location: NSURL)
        {
            if let downloadTaskDidFinishDownloadingToURL = downloadTaskDidFinishDownloadingToURL {
                downloadTaskDidFinishDownloadingToURL(session, downloadTask, location)
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
                delegate.URLSession(session, downloadTask: downloadTask, didFinishDownloadingToURL: location)
            }
        }

        /**
            Periodically informs the delegate about the download’s progress.

            - parameter session:                   The session containing the download task.
            - parameter downloadTask:              The download task.
            - parameter bytesWritten:              The number of bytes transferred since the last time this delegate 
                                                   method was called.
            - parameter totalBytesWritten:         The total number of bytes transferred so far.
            - parameter totalBytesExpectedToWrite: The expected length of the file, as provided by the Content-Length 
                                                   header. If this header was not provided, the value is 
                                                   `NSURLSessionTransferSizeUnknown`.
        */
        public func URLSession(
            session: NSURLSession,
            downloadTask: NSURLSessionDownloadTask,
            didWriteData bytesWritten: Int64,
            totalBytesWritten: Int64,
            totalBytesExpectedToWrite: Int64)
        {
            if let downloadTaskDidWriteData = downloadTaskDidWriteData {
                downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite)
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
                delegate.URLSession(
                    session,
                    downloadTask: downloadTask,
                    didWriteData: bytesWritten,
                    totalBytesWritten: totalBytesWritten,
                    totalBytesExpectedToWrite: totalBytesExpectedToWrite
                )
            }
        }

        /**
            Tells the delegate that the download task has resumed downloading.

            - parameter session:            The session containing the download task that finished.
            - parameter downloadTask:       The download task that resumed. See explanation in the discussion.
            - parameter fileOffset:         If the file's cache policy or last modified date prevents reuse of the 
                                            existing content, then this value is zero. Otherwise, this value is an 
                                            integer representing the number of bytes on disk that do not need to be 
                                            retrieved again.
            - parameter expectedTotalBytes: The expected length of the file, as provided by the Content-Length header. 
                                            If this header was not provided, the value is NSURLSessionTransferSizeUnknown.
        */
        public func URLSession(
            session: NSURLSession,
            downloadTask: NSURLSessionDownloadTask,
            didResumeAtOffset fileOffset: Int64,
            expectedTotalBytes: Int64)
        {
            if let downloadTaskDidResumeAtOffset = downloadTaskDidResumeAtOffset {
                downloadTaskDidResumeAtOffset(session, downloadTask, fileOffset, expectedTotalBytes)
            } else if let delegate = self[downloadTask] as? Request.DownloadTaskDelegate {
                delegate.URLSession(
                    session,
                    downloadTask: downloadTask,
                    didResumeAtOffset: fileOffset,
                    expectedTotalBytes: expectedTotalBytes
                )
            }
        }

        // MARK: - NSURLSessionStreamDelegate

        var _streamTaskReadClosed: Any?
        var _streamTaskWriteClosed: Any?
        var _streamTaskBetterRouteDiscovered: Any?
        var _streamTaskDidBecomeInputStream: Any?

        // MARK: - NSObject

        public override func respondsToSelector(selector: Selector) -> Bool {
            #if !os(OSX)
                if selector == #selector(NSURLSessionDelegate.URLSessionDidFinishEventsForBackgroundURLSession(_:)) {
                    return sessionDidFinishEventsForBackgroundURLSession != nil
                }
            #endif

            switch selector {
            case #selector(NSURLSessionDelegate.URLSession(_:didBecomeInvalidWithError:)):
                return sessionDidBecomeInvalidWithError != nil
            case #selector(NSURLSessionDelegate.URLSession(_:didReceiveChallenge:completionHandler:)):
                return sessionDidReceiveChallenge != nil
            case #selector(NSURLSessionTaskDelegate.URLSession(_:task:willPerformHTTPRedirection:newRequest:completionHandler:)):
                return taskWillPerformHTTPRedirection != nil
            case #selector(NSURLSessionDataDelegate.URLSession(_:dataTask:didReceiveResponse:completionHandler:)):
                return dataTaskDidReceiveResponse != nil
            default:
                return self.dynamicType.instancesRespondToSelector(selector)
            }
        }
    }
}
