// Stream.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

#if !os(watchOS)

@available(iOS 9.0, OSX 10.11, tvOS 9.0, *)
extension Manager {
    private enum Streamable {
        case Stream(String, Int)
        case NetService(NSNetService)
    }

    private func stream(streamable: Streamable) -> Request {
        var streamTask: NSURLSessionStreamTask!

        switch streamable {
        case .Stream(let hostName, let port):
            dispatch_sync(queue) {
                streamTask = self.session.streamTaskWithHostName(hostName, port: port)
            }
        case .NetService(let netService):
            dispatch_sync(queue) {
                streamTask = self.session.streamTaskWithNetService(netService)
            }
        }

        let request = Request(session: session, task: streamTask)

        delegate[request.delegate.task] = request.delegate

        if startRequestsImmediately {
            request.resume()
        }

        return request
    }

    /**
        Creates a request for bidirectional streaming with the given hostname and port.

        - parameter hostName: The hostname of the server to connect to.
        - parameter port:     The port of the server to connect to.

        :returns: The created stream request.
    */
    public func stream(hostName hostName: String, port: Int) -> Request {
        return stream(.Stream(hostName, port))
    }

    /**
        Creates a request for bidirectional streaming with the given `NSNetService`.

        - parameter netService: The net service used to identify the endpoint.

        - returns: The created stream request.
    */
    public func stream(netService netService: NSNetService) -> Request {
        return stream(.NetService(netService))
    }
}

// MARK: -

@available(iOS 9.0, OSX 10.11, tvOS 9.0, *)
extension Manager.SessionDelegate: NSURLSessionStreamDelegate {

    // MARK: Override Closures

    /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:readClosedForStreamTask:`.
    public var streamTaskReadClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
        get {
            return _streamTaskReadClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void
        }
        set {
            _streamTaskReadClosed = newValue
        }
    }

    /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:writeClosedForStreamTask:`.
    public var streamTaskWriteClosed: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
        get {
            return _streamTaskWriteClosed as? (NSURLSession, NSURLSessionStreamTask) -> Void
        }
        set {
            _streamTaskWriteClosed = newValue
        }
    }

    /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:betterRouteDiscoveredForStreamTask:`.
    public var streamTaskBetterRouteDiscovered: ((NSURLSession, NSURLSessionStreamTask) -> Void)? {
        get {
            return _streamTaskBetterRouteDiscovered as? (NSURLSession, NSURLSessionStreamTask) -> Void
        }
        set {
            _streamTaskBetterRouteDiscovered = newValue
        }
    }

    /// Overrides default behavior for NSURLSessionStreamDelegate method `URLSession:streamTask:didBecomeInputStream:outputStream:`.
    public var streamTaskDidBecomeInputStream: ((NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void)? {
        get {
            return _streamTaskDidBecomeInputStream as? (NSURLSession, NSURLSessionStreamTask, NSInputStream, NSOutputStream) -> Void
        }
        set {
            _streamTaskDidBecomeInputStream = newValue
        }
    }

    // MARK: Delegate Methods

    /**
        Tells the delegate that the read side of the connection has been closed.

        - parameter session:    The session.
        - parameter streamTask: The stream task.
    */
    public func URLSession(session: NSURLSession, readClosedForStreamTask streamTask: NSURLSessionStreamTask) {
        streamTaskReadClosed?(session, streamTask)
    }

    /**
        Tells the delegate that the write side of the connection has been closed.

        - parameter session:    The session.
        - parameter streamTask: The stream task.
    */
    public func URLSession(session: NSURLSession, writeClosedForStreamTask streamTask: NSURLSessionStreamTask) {
        streamTaskWriteClosed?(session, streamTask)
    }

    /**
        Tells the delegate that the system has determined that a better route to the host is available.

        - parameter session:    The session.
        - parameter streamTask: The stream task.
    */
    public func URLSession(session: NSURLSession, betterRouteDiscoveredForStreamTask streamTask: NSURLSessionStreamTask) {
        streamTaskBetterRouteDiscovered?(session, streamTask)
    }

    /**
        Tells the delegate that the stream task has been completed and provides the unopened stream objects.

        - parameter session:      The session.
        - parameter streamTask:   The stream task.
        - parameter inputStream:  The new input stream.
        - parameter outputStream: The new output stream.
    */
    public func URLSession(
        session: NSURLSession,
        streamTask: NSURLSessionStreamTask,
        didBecomeInputStream inputStream: NSInputStream,
        outputStream: NSOutputStream)
    {
        streamTaskDidBecomeInputStream?(session, streamTask, inputStream, outputStream)
    }
}

#endif
