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


/// An `URLResponse` object represents a URL load response in a
/// manner independent of protocol and URL scheme.
///
/// `URLResponse` encapsulates the metadata associated
/// with a URL load. Note that URLResponse objects do not contain
/// the actual bytes representing the content of a URL. See
/// `URLSession` for more information about receiving the content
/// data for a URL load.
open class URLResponse : NSObject, NSSecureCoding, NSCopying {

    static public var supportsSecureCoding: Bool {
        return true
    }
    
    public required init?(coder aDecoder: NSCoder) {
        guard aDecoder.allowsKeyedCoding else {
            preconditionFailure("Unkeyed coding is unsupported.")
        }
        
        if let encodedUrl = aDecoder.decodeObject(forKey: "NS.url") as? NSURL {
            self.url = encodedUrl._swiftObject
        }
        
        if let encodedMimeType = aDecoder.decodeObject(forKey: "NS.mimeType") as? NSString {
            self.mimeType = encodedMimeType._swiftObject
        }
        
        self.expectedContentLength = aDecoder.decodeInt64(forKey: "NS.expectedContentLength")
        
        if let encodedEncodingName = aDecoder.decodeObject(forKey: "NS.textEncodingName") as? NSString {
            self.textEncodingName = encodedEncodingName._swiftObject
        }
        
        if let encodedFilename = aDecoder.decodeObject(forKey: "NS.suggestedFilename") as? NSString {
            self.suggestedFilename = encodedFilename._swiftObject
        }
    }
    
    open func encode(with aCoder: NSCoder) {
        guard aCoder.allowsKeyedCoding else {
            preconditionFailure("Unkeyed coding is unsupported.")
        }
        
        aCoder.encode(self.url?._bridgeToObjectiveC(), forKey: "NS.url")
        aCoder.encode(self.mimeType?._bridgeToObjectiveC(), forKey: "NS.mimeType")
        aCoder.encode(self.expectedContentLength, forKey: "NS.expectedContentLength")
        aCoder.encode(self.textEncodingName?._bridgeToObjectiveC(), forKey: "NS.textEncodingName")
        aCoder.encode(self.suggestedFilename?._bridgeToObjectiveC(), forKey: "NS.suggestedFilename")
    }
    
    open override func copy() -> Any {
        return copy(with: nil)
    }
    
    open func copy(with zone: NSZone? = nil) -> Any {
        return self
    }
    
    /// Initialize an URLResponse with the provided values.
    ///
    /// This is the designated initializer for URLResponse.
    /// - Parameter URL: the URL
    /// - Parameter mimeType: the MIME content type of the response
    /// - Parameter expectedContentLength: the expected content length of the associated data
    /// - Parameter textEncodingName the name of the text encoding for the associated data, if applicable, else nil
    /// - Returns: The initialized URLResponse.
    public init(url: URL, mimeType: String?, expectedContentLength length: Int, textEncodingName name: String?) {
        self.url = url
        self.mimeType = mimeType
        self.expectedContentLength = Int64(length)
        self.textEncodingName = name
        let c = url.lastPathComponent
        self.suggestedFilename = c.isEmpty ? "Unknown" : c
    }
    
    /// The URL of the receiver.
    /*@NSCopying*/ open private(set) var url: URL?

    
    /// The MIME type of the receiver.
    ///
    /// The MIME type is based on the information provided
    /// from an origin source. However, that value may be changed or
    /// corrected by a protocol implementation if it can be determined
    /// that the origin server or source reported the information
    /// incorrectly or imprecisely. An attempt to guess the MIME type may
    /// be made if the origin source did not report any such information.
    open fileprivate(set) var mimeType: String?
    
    /// The expected content length of the receiver.
    ///
    /// Some protocol implementations report a content length
    /// as part of delivering load metadata, but not all protocols
    /// guarantee the amount of data that will be delivered in actuality.
    /// Hence, this method returns an expected amount. Clients should use
    /// this value as an advisory, and should be prepared to deal with
    /// either more or less data.
    ///
    /// The expected content length of the receiver, or `-1` if
    /// there is no expectation that can be arrived at regarding expected
    /// content length.
    open fileprivate(set) var expectedContentLength: Int64
    
    /// The name of the text encoding of the receiver.
    ///
    /// This name will be the actual string reported by the
    /// origin source during the course of performing a protocol-specific
    /// URL load. Clients can inspect this string and convert it to an
    /// NSStringEncoding or CFStringEncoding using the methods and
    /// functions made available in the appropriate framework.
    open fileprivate(set) var textEncodingName: String?
    
    /// A suggested filename if the resource were saved to disk.
    ///
    /// The method first checks if the server has specified a filename
    /// using the content disposition header. If no valid filename is
    /// specified using that mechanism, this method checks the last path
    /// component of the URL. If no valid filename can be obtained using
    /// the last path component, this method uses the URL's host as the
    /// filename. If the URL's host can't be converted to a valid
    /// filename, the filename "unknown" is used. In mose cases, this
    /// method appends the proper file extension based on the MIME type.
    ///
    /// This method always returns a valid filename.
    open fileprivate(set) var suggestedFilename: String?
}

/// A Response to an HTTP URL load.
///
/// An HTTPURLResponse object represents a response to an
/// HTTP URL load. It is a specialization of URLResponse which
/// provides conveniences for accessing information specific to HTTP
/// protocol responses.
open class HTTPURLResponse : URLResponse {
    
    /// Initializer for HTTPURLResponse objects.
    ///
    /// - Parameter url: the URL from which the response was generated.
    /// - Parameter statusCode: an HTTP status code.
    /// - Parameter httpVersion: The version of the HTTP response as represented by the server.  This is typically represented as "HTTP/1.1".
    /// - Parameter headerFields: A dictionary representing the header keys and values of the server response.
    /// - Returns: the instance of the object, or `nil` if an error occurred during initialization.
    public init?(url: URL, statusCode: Int, httpVersion: String?, headerFields: [String : String]?) {
        self.statusCode = statusCode
        self.allHeaderFields = headerFields ?? [:]
        super.init(url: url, mimeType: nil, expectedContentLength: 0, textEncodingName: nil)
        expectedContentLength = getExpectedContentLength(fromHeaderFields: headerFields) ?? -1
        suggestedFilename = getSuggestedFilename(fromHeaderFields: headerFields) ?? "Unknown"
        if let type = ContentTypeComponents(headerFields: headerFields) {
            mimeType = type.mimeType.lowercased()
            textEncodingName = type.textEncoding?.lowercased()
        }
    }
    
    public required init?(coder aDecoder: NSCoder) {
        guard aDecoder.allowsKeyedCoding else {
            preconditionFailure("Unkeyed coding is unsupported.")
        }
        
        self.statusCode = aDecoder.decodeInteger(forKey: "NS.statusCode")
        
        if let encodedHeaders = aDecoder.decodeObject(forKey: "NS.allHeaderFields") as? NSDictionary {
            self.allHeaderFields = encodedHeaders._swiftObject
        } else {
            self.allHeaderFields = [:]
        }
        
        super.init(coder: aDecoder)
    }
    
    open override func encode(with aCoder: NSCoder) {
        super.encode(with: aCoder) //Will fail if .allowsKeyedCoding == false
        
        aCoder.encode(self.statusCode, forKey: "NS.statusCode")
        aCoder.encode(self.allHeaderFields._bridgeToObjectiveC(), forKey: "NS.allHeaderFields")
        
    }
    
    /// The HTTP status code of the receiver.
    public let statusCode: Int
    
    /// Returns a dictionary containing all the HTTP header fields
    /// of the receiver.
    ///
    /// By examining this header dictionary, clients can see
    /// the "raw" header information which was reported to the protocol
    /// implementation by the HTTP server. This may be of use to
    /// sophisticated or special-purpose HTTP clients.
    ///
    /// - Returns: A dictionary containing all the HTTP header fields of the
    /// receiver.
    ///
    /// - Important: This is an *experimental* change from the
    /// `[NSObject: AnyObject]` type that Darwin Foundation uses.
    public let allHeaderFields: [AnyHashable : Any]
    
    /// Convenience method which returns a localized string
    /// corresponding to the status code for this response.
    /// - Parameter forStatusCode: the status code to use to produce a localized string.
    open class func localizedString(forStatusCode statusCode: Int) -> String {
        switch statusCode {
        case 100: return "Continue"
        case 101: return "Switching Protocols"
        case 102: return "Processing"
        case 100...199: return "Informational"
        case 200: return "OK"
        case 201: return "Created"
        case 202: return "Accepted"
        case 203: return "Non-Authoritative Information"
        case 204: return "No Content"
        case 205: return "Reset Content"
        case 206: return "Partial Content"
        case 207: return "Multi-Status"
        case 208: return "Already Reported"
        case 226: return "IM Used"
        case 200...299: return "Success"
        case 300: return "Multiple Choices"
        case 301: return "Moved Permanently"
        case 302: return "Found"
        case 303: return "See Other"
        case 304: return "Not Modified"
        case 305: return "Use Proxy"
        case 307: return "Temporary Redirect"
        case 308: return "Permanent Redirect"
        case 300...399: return "Redirection"
        case 400: return "Bad Request"
        case 401: return "Unauthorized"
        case 402: return "Payment Required"
        case 403: return "Forbidden"
        case 404: return "Not Found"
        case 405: return "Method Not Allowed"
        case 406: return "Not Acceptable"
        case 407: return "Proxy Authentication Required"
        case 408: return "Request Timeout"
        case 409: return "Conflict"
        case 410: return "Gone"
        case 411: return "Length Required"
        case 412: return "Precondition Failed"
        case 413: return "Payload Too Large"
        case 414: return "URI Too Long"
        case 415: return "Unsupported Media Type"
        case 416: return "Range Not Satisfiable"
        case 417: return "Expectation Failed"
        case 421: return "Misdirected Request"
        case 422: return "Unprocessable Entity"
        case 423: return "Locked"
        case 424: return "Failed Dependency"
        case 426: return "Upgrade Required"
        case 428: return "Precondition Required"
        case 429: return "Too Many Requests"
        case 431: return "Request Header Fields Too Large"
        case 451: return "Unavailable For Legal Reasons"
        case 400...499: return "Client Error"
        case 500: return "Internal Server Error"
        case 501: return "Not Implemented"
        case 502: return "Bad Gateway"
        case 503: return "Service Unavailable"
        case 504: return "Gateway Timeout"
        case 505: return "HTTP Version Not Supported"
        case 506: return "Variant Also Negotiates"
        case 507: return "Insufficient Storage"
        case 508: return "Loop Detected"
        case 510: return "Not Extended"
        case 511: return "Network Authentication Required"
        case 500...599: return "Server Error"
        default: return "Server Error"
        }
    }

    /// A string that represents the contents of the HTTPURLResponse Object.
    /// This property is intended to produce readable output.
    override open var description: String {
        var result = "<\(type(of: self)) \(Unmanaged.passUnretained(self).toOpaque())> { URL: \(url!.absoluteString) }{ status: \(statusCode), headers {\n"
        for(aKey, aValue) in allHeaderFields {
            guard let key = aKey as? String, let value = aValue as? String else { continue } //shouldn't typically fail here 
            if((key.lowercased() == "content-disposition" && suggestedFilename != "Unknown") || key.lowercased() == "content-type") {
                result += "   \"\(key)\" = \"\(value)\";\n"
            } else {
                result += "   \"\(key)\" = \(value);\n"
            }
        }
        result += "} }"
        return result
    }
}

/// Parses the expected content length from the headers.
///
/// Note that the message content length is different from the message
/// transfer length.
/// The transfer length can only be derived when the Transfer-Encoding is identity (default).
/// For compressed content (Content-Encoding other than identity), there is not way to derive the
/// content length from the transfer length.
private func getExpectedContentLength(fromHeaderFields headerFields: [String : String]?) -> Int64? {
    guard
        let f = headerFields,
        let contentLengthS = valueForCaseInsensitiveKey("content-length", fields: f),
        let contentLength = Int64(contentLengthS)
        else { return nil }
    return contentLength
}
/// Parses the suggested filename from the `Content-Disposition` header.
///
/// - SeeAlso: [RFC 2183](https://tools.ietf.org/html/rfc2183)
private func getSuggestedFilename(fromHeaderFields headerFields: [String : String]?) -> String? {
    // Typical use looks like this:
    //     Content-Disposition: attachment; filename="fname.ext"
    guard
        let f = headerFields,
        let contentDisposition = valueForCaseInsensitiveKey("content-disposition", fields: f),
        let field = contentDisposition.httpHeaderParts
        else { return nil }
    for part in field.parameters where part.attribute == "filename" {
        if let path = part.value {
            return _pathComponents(path)?.map{ $0 == "/" ? "" : $0}.joined(separator: "_")
        } else {
            return nil
        }
    }
    return nil
}
/// Parts corresponding to the `Content-Type` header field in a HTTP message.
private struct ContentTypeComponents {
    /// For `text/html; charset=ISO-8859-4` this would be `text/html`
    let mimeType: String
    /// For `text/html; charset=ISO-8859-4` this would be `ISO-8859-4`. Will be
    /// `nil` when no `charset` is specified.
    let textEncoding: String?
}
extension ContentTypeComponents {
    /// Parses the `Content-Type` header field
    ///
    /// `Content-Type: text/html; charset=ISO-8859-4` would result in `("text/html", "ISO-8859-4")`, while
    /// `Content-Type: text/html` would result in `("text/html", nil)`.
    init?(headerFields: [String : String]?) {
        guard
            let f = headerFields,
            let contentType = valueForCaseInsensitiveKey("content-type", fields: f),
            let field = contentType.httpHeaderParts
            else { return nil }
        for parameter in field.parameters where parameter.attribute == "charset" {
            self.mimeType = field.value
            self.textEncoding = parameter.value
            return
        }
        self.mimeType = field.value
        self.textEncoding = nil
    }
}

/// A type with paramteres
///
/// RFC 2616 specifies a few types that can have parameters, e.g. `Content-Type`.
/// These are specified like so
/// ```
/// field          = value *( ";" parameter )
/// value          = token
/// ```
/// where parameters are attribute/value as specified by
/// ```
/// parameter               = attribute "=" value
/// attribute               = token
/// value                   = token | quoted-string
/// ```
private struct ValueWithParameters {
    let value: String
    let parameters: [Parameter]
    struct Parameter {
        let attribute: String
        let value: String?
    }
}

private extension String {
    /// Split the string at each ";", remove any quoting.
    /// 
    /// The trouble is if there's a
    /// ";" inside something that's quoted. And we can escape the separator and
    /// the quotes with a "\".
    var httpHeaderParts: ValueWithParameters? {
        var type: String?
        var parameters: [ValueWithParameters.Parameter] = []
        let ws = CharacterSet.whitespaces
        func append(_ string: String) {
            if type == nil {
                type = string
            } else {
                if let r = string.range(of: "=") {
                    let name = String(string[string.startIndex..<r.lowerBound]).trimmingCharacters(in: ws)
                    let value = String(string[r.upperBound..<string.endIndex]).trimmingCharacters(in: ws)
                    parameters.append(ValueWithParameters.Parameter(attribute: name, value: value))
                } else {
                    let name = string.trimmingCharacters(in: ws)
                    parameters.append(ValueWithParameters.Parameter(attribute: name, value: nil))
                }
            }
        }
        
        let escape = UnicodeScalar(0x5c)!    //  \
        let quote = UnicodeScalar(0x22)!     //  "
        let separator = UnicodeScalar(0x3b)! //  ;
        enum State {
            case nonQuoted(String)
            case nonQuotedEscaped(String)
            case quoted(String)
            case quotedEscaped(String)
        }
        var state = State.nonQuoted("")
        for next in unicodeScalars {
            switch (state, next) {
            case (.nonQuoted(let s), separator):
                append(s)
                state = .nonQuoted("")
            case (.nonQuoted(let s), escape):
                state = .nonQuotedEscaped(s + String(next))
            case (.nonQuoted(let s), quote):
                state = .quoted(s)
            case (.nonQuoted(let s), _):
                state = .nonQuoted(s + String(next))
                
            case (.nonQuotedEscaped(let s), _):
                state = .nonQuoted(s + String(next))
                
            case (.quoted(let s), quote):
                state = .nonQuoted(s)
            case (.quoted(let s), escape):
                state = .quotedEscaped(s + String(next))
            case (.quoted(let s), _):
                state = .quoted(s + String(next))
            
            case (.quotedEscaped(let s), _):
                state = .quoted(s + String(next))
            }
        }
        switch state {
            case .nonQuoted(let s): append(s)
            case .nonQuotedEscaped(let s): append(s)
            case .quoted(let s): append(s)
            case .quotedEscaped(let s): append(s)
        }
        guard let t = type else { return nil }
        return ValueWithParameters(value: t, parameters: parameters)
    }
}
private func valueForCaseInsensitiveKey(_ key: String, fields: [String: String]) -> String? {
    let kk = key.lowercased()
    for (k, v) in fields {
        if k.lowercased() == kk {
            return v
        }
    }
    return nil
}
