// 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 struct HTTPCookiePropertyKey : RawRepresentable, Equatable, Hashable {
    public private(set) var rawValue: String
    
    public init(_ rawValue: String) {
        self.rawValue = rawValue
    }
    
    public init(rawValue: String) {
        self.rawValue = rawValue
    }
    
    public var hashValue: Int {
        return self.rawValue.hashValue
    }
    
    public static func ==(_ lhs: HTTPCookiePropertyKey, _ rhs: HTTPCookiePropertyKey) -> Bool {
        return lhs.rawValue == rhs.rawValue
    }
}

extension HTTPCookiePropertyKey {
    /// Key for cookie name
    public static let name = HTTPCookiePropertyKey(rawValue: "Name")

    /// Key for cookie value
    public static let value = HTTPCookiePropertyKey(rawValue: "Value")

    /// Key for cookie origin URL
    public static let originURL = HTTPCookiePropertyKey(rawValue: "OriginURL")

    /// Key for cookie version
    public static let version = HTTPCookiePropertyKey(rawValue: "Version")

    /// Key for cookie domain
    public static let domain = HTTPCookiePropertyKey(rawValue: "Domain")

    /// Key for cookie path
    public static let path = HTTPCookiePropertyKey(rawValue: "Path")

    /// Key for cookie secure flag
    public static let secure = HTTPCookiePropertyKey(rawValue: "Secure")

    /// Key for cookie expiration date
    public static let expires = HTTPCookiePropertyKey(rawValue: "Expires")

    /// Key for cookie comment text
    public static let comment = HTTPCookiePropertyKey(rawValue: "Comment")

    /// Key for cookie comment URL
    public static let commentURL = HTTPCookiePropertyKey(rawValue: "CommentURL")

    /// Key for cookie discard (session-only) flag
    public static let discard = HTTPCookiePropertyKey(rawValue: "Discard")

    /// Key for cookie maximum age (an alternate way of specifying the expiration)
    public static let maximumAge = HTTPCookiePropertyKey(rawValue: "Max-Age")

    /// Key for cookie ports
    public static let port = HTTPCookiePropertyKey(rawValue: "Port")

    // For Cocoa compatibility
    internal static let created = HTTPCookiePropertyKey(rawValue: "Created")
}

/// `HTTPCookie` represents an http cookie.
///
/// An `HTTPCookie` instance represents a single http cookie. It is
/// an immutable object initialized from a dictionary that contains
/// the various cookie attributes. It has accessors to get the various
/// attributes of a cookie.
open class HTTPCookie : NSObject {

    let _comment: String?
    let _commentURL: URL?
    let _domain: String
    let _expiresDate: Date?
    let _HTTPOnly: Bool
    let _secure: Bool
    let _sessionOnly: Bool
    let _name: String
    let _path: String
    let _portList: [NSNumber]?
    let _value: String
    let _version: Int
    var _properties: [HTTPCookiePropertyKey : Any]

    static let _attributes: [HTTPCookiePropertyKey]
        = [.name, .value, .originURL, .version, .domain,
           .path, .secure, .expires, .comment, .commentURL,
           .discard, .maximumAge, .port]

    /// Initialize a HTTPCookie object with a dictionary of parameters
    ///
    /// - Parameter properties: The dictionary of properties to be used to
    /// initialize this cookie.
    ///
    /// Supported dictionary keys and value types for the
    /// given dictionary are as follows.
    ///
    /// All properties can handle an NSString value, but some can also
    /// handle other types.
    ///
    /// <table border=1 cellspacing=2 cellpadding=4>
    /// <tr>
    ///     <th>Property key constant</th>
    ///     <th>Type of value</th>
    ///     <th>Required</th>
    ///     <th>Description</th>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.comment</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>Comment for the cookie. Only valid for version 1 cookies and
    ///     later. Default is nil.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.commentURL</td>
    ///     <td>NSURL or NSString</td>
    ///     <td>NO</td>
    ///     <td>Comment URL for the cookie. Only valid for version 1 cookies
    ///     and later. Default is nil.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.domain</td>
    ///     <td>NSString</td>
    ///     <td>Special, a value for either .originURL or
    ///     HTTPCookiePropertyKey.domain must be specified.</td>
    ///     <td>Domain for the cookie. Inferred from the value for
    ///     HTTPCookiePropertyKey.originURL if not provided.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.discard</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string stating whether the cookie should be discarded at
    ///     the end of the session. String value must be either "TRUE" or
    ///     "FALSE". Default is "FALSE", unless this is cookie is version
    ///     1 or greater and a value for HTTPCookiePropertyKey.maximumAge is not
    ///     specified, in which case it is assumed "TRUE".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.expires</td>
    ///     <td>NSDate or NSString</td>
    ///     <td>NO</td>
    ///     <td>Expiration date for the cookie. Used only for version 0
    ///     cookies. Ignored for version 1 or greater.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.maximumAge</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string containing an integer value stating how long in
    ///     seconds the cookie should be kept, at most. Only valid for
    ///     version 1 cookies and later. Default is "0".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.name</td>
    ///     <td>NSString</td>
    ///     <td>YES</td>
    ///     <td>Name of the cookie</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.originURL</td>
    ///     <td>NSURL or NSString</td>
    ///     <td>Special, a value for either HTTPCookiePropertyKey.originURL or
    ///     HTTPCookiePropertyKey.domain must be specified.</td>
    ///     <td>URL that set this cookie. Used as default for other fields
    ///     as noted.</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.path</td>
    ///     <td>NSString</td>
    ///     <td>YES</td>
    ///     <td>Path for the cookie</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.port</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>comma-separated integer values specifying the ports for the
    ///     cookie. Only valid for version 1 cookies and later. Default is
    ///     empty string ("").</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.secure</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>A string stating whether the cookie should be transmitted
    ///     only over secure channels. String value must be either "TRUE"
    ///     or "FALSE". Default is "FALSE".</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.value</td>
    ///     <td>NSString</td>
    ///     <td>YES</td>
    ///     <td>Value of the cookie</td>
    /// </tr>
    /// <tr>
    ///     <td>HTTPCookiePropertyKey.version</td>
    ///     <td>NSString</td>
    ///     <td>NO</td>
    ///     <td>Specifies the version of the cookie. Must be either "0" or
    ///     "1". Default is "0".</td>
    /// </tr>
    /// </table>
    ///
    /// All other keys are ignored.
    ///
    /// - Returns: An initialized `HTTPCookie`, or nil if the set of
    /// dictionary keys is invalid, for example because a required key is
    /// missing, or a recognized key maps to an illegal value.
    ///
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
    /// - Note: Since this API is under consideration it may be either removed or revised in the near future
    public init?(properties: [HTTPCookiePropertyKey : Any]) {
        guard
            let path = properties[.path] as? String,
            let name = properties[.name] as? String,
            let value = properties[.value] as? String
        else {
            return nil
        }

        let canonicalDomain: String
        if let domain = properties[.domain] as? String {
            canonicalDomain = domain
        } else if
            let originURL = properties[.originURL] as? URL,
            let host = originURL.host
        {
            canonicalDomain = host
        } else {
            return nil
        }

        _path = path
        _name = name
        _value = value
        _domain = canonicalDomain

        if let
            secureString = properties[.secure] as? String, !secureString.characters.isEmpty
        {
            _secure = true
        } else {
            _secure = false
        }

        let version: Int
        if let
            versionString = properties[.version] as? String, versionString == "1"
        {
            version = 1
        } else {
            version = 0
        }
        _version = version

        if let portString = properties[.port] as? String, _version == 1 {
            _portList = portString.characters
                .split(separator: ",")
                .flatMap { Int(String($0)) }
                .map { NSNumber(value: $0) }
        } else {
            _portList = nil
        }

        // TODO: factor into a utility function
        if version == 0 {
            let expiresProperty = properties[.expires]
            if let date = expiresProperty as? Date {
                _expiresDate = date
            } else if let dateString = expiresProperty as? String {
                let formatter = DateFormatter()
                formatter.locale = Locale(identifier: "en_US_POSIX")
                formatter.dateFormat = "EEE, dd MMM yyyy HH:mm:ss O"   // per RFC 6265 '<rfc1123-date, defined in [RFC2616], Section 3.3.1>'
                let timeZone = TimeZone(abbreviation: "GMT")
                formatter.timeZone = timeZone
                _expiresDate = formatter.date(from: dateString)
            } else {
                _expiresDate = nil
            }
        } else if
            let maximumAge = properties[.maximumAge] as? String,
            let secondsFromNow = Int(maximumAge), _version == 1 {
            _expiresDate = Date(timeIntervalSinceNow: Double(secondsFromNow))
        } else {
            _expiresDate = nil
        }

        if let discardString = properties[.discard] as? String {
            _sessionOnly = discardString == "TRUE"
        } else {
            _sessionOnly = properties[.maximumAge] == nil && version >= 1
        }
        if version == 0 {
            _comment = nil
            _commentURL = nil
        } else {
            _comment = properties[.comment] as? String
            if let commentURL = properties[.commentURL] as? URL {
                _commentURL = commentURL
            } else if let commentURL = properties[.commentURL] as? String {
                _commentURL = URL(string: commentURL)
            } else {
                _commentURL = nil
            }
        }
        _HTTPOnly = false


        _properties = [
            .created : Date().timeIntervalSinceReferenceDate, // Cocoa Compatibility
            .discard : _sessionOnly,
            .domain : _domain,
            .name : _name,
            .path : _path,
            .secure : _secure,
            .value : _value,
            .version : _version
        ]
        if let comment = properties[.comment] {
            _properties[.comment] = comment
        }
        if let commentURL = properties[.commentURL] {
            _properties[.commentURL] = commentURL
        }
        if let expires = properties[.expires] {
            _properties[.expires] = expires
        }
        if let maximumAge = properties[.maximumAge] {
            _properties[.maximumAge] = maximumAge
        }
        if let originURL = properties[.originURL] {
            _properties[.originURL] = originURL
        }
        if let _portList = _portList {
            _properties[.port] = _portList
        }
    }

    /// Return a dictionary of header fields that can be used to add the
    /// specified cookies to the request.
    ///
    /// - Parameter cookies: The cookies to turn into request headers.
    /// - Returns: A dictionary where the keys are header field names, and the values
    /// are the corresponding header field values.
    open class func requestHeaderFields(with cookies: [HTTPCookie]) -> [String : String] {
        var cookieString = cookies.reduce("") { (sum, next) -> String in
            return sum + "\(next._name)=\(next._value); "
        }
        //Remove the final trailing semicolon and whitespace
        if ( cookieString.length > 0 ) {
            cookieString.characters.removeLast()
            cookieString.characters.removeLast()
        }
        return ["Cookie": cookieString]
    }

    /// Return an array of cookies parsed from the specified response header fields and URL.
    ///
    /// This method will ignore irrelevant header fields so
    /// you can pass a dictionary containing data other than cookie data.
    /// - Parameter headerFields: The response header fields to check for cookies.
    /// - Parameter URL: The URL that the cookies came from - relevant to how the cookies are interpeted.
    /// - Returns: An array of HTTPCookie objects
    open class func cookies(withResponseHeaderFields headerFields: [String : String], for URL: URL) -> [HTTPCookie] {

        //HTTP Cookie parsing based on RFC 6265: https://tools.ietf.org/html/rfc6265
        //Though RFC6265 suggests that multiple cookies cannot be folded into a single Set-Cookie field, this is
        //pretty common. It also suggests that commas and semicolons among other characters, cannot be a part of 
        // names and values. This implementation takes care of multiple cookies in the same field, however it doesn't   
        //support commas and semicolons in names and values(except for dates)

        guard let cookies: String = headerFields["Set-Cookie"]  else { return [] }

        let nameValuePairs = cookies.components(separatedBy: ";")          //split the name/value and attribute/value pairs
                                .map({$0.trim()})                           //trim whitespaces
                                .map({removeCommaFromDate($0)})     //get rid of commas in dates
                                .flatMap({$0.components(separatedBy: ",")}) //cookie boundaries are marked by commas
                                .map({$0.trim()})                           //trim again
                                .filter({$0.caseInsensitiveCompare("HTTPOnly") != .orderedSame})  //we don't use HTTPOnly, do we?
                                .flatMap({createNameValuePair(pair: $0)})   //create Name and Value properties 

        //mark cookie boundaries in the name-value array
        var cookieIndices = (0..<nameValuePairs.count).filter({nameValuePairs[$0].hasPrefix("Name")})
        cookieIndices.append(nameValuePairs.count)

        //bake the cookies
        var httpCookies: [HTTPCookie] = []
        for i in 0..<cookieIndices.count-1 {
            if let aCookie = createHttpCookie(url: URL, pairs: nameValuePairs[cookieIndices[i]..<cookieIndices[i+1]]) {
                httpCookies.append(aCookie)
            }
        }

        return httpCookies
    }

    //Bake a cookie
    private class func createHttpCookie(url: URL, pairs: ArraySlice<String>) -> HTTPCookie? {
        var properties: [HTTPCookiePropertyKey : Any] = [:]
        for pair in pairs {
            let name = pair.components(separatedBy: "=")[0]
            var value = pair.components(separatedBy: "\(name)=")[1]  //a value can have an "="
            if canonicalize(name) == .expires {
                value = value.insertComma(at: 3)    //re-insert the comma
            }
            properties[canonicalize(name)] = value
        }

        //if domain wasn't provided use the URL
        if properties[.domain] == nil {
            properties[.domain] = url.absoluteString
        }

        //the default Path is "/"
        if properties[.path] == nil {
            properties[.path] = "/"
        }

        return HTTPCookie(properties: properties)
    }

    //we pass this to a map()
    private class func removeCommaFromDate(_ value: String) -> String {
        if value.hasPrefix("Expires") || value.hasPrefix("expires")  {
            return value.removeCommas()
        }
        return value
    }

    //These cookie attributes are defined in RFC 6265 and 2965(which is obsolete)
    //HTTPCookie supports these
    private class func isCookieAttribute(_ string: String) -> Bool {
        return _attributes.first(where: {$0.rawValue.caseInsensitiveCompare(string) == .orderedSame}) != nil
    }

    //Cookie attribute names are case-insensitive as per RFC6265: https://tools.ietf.org/html/rfc6265
    //but HTTPCookie needs only the first letter of each attribute in uppercase
    private class func canonicalize(_ name: String) -> HTTPCookiePropertyKey {
        let idx = _attributes.index(where: {$0.rawValue.caseInsensitiveCompare(name) == .orderedSame})!
        return _attributes[idx]
    }

    //A name=value pair should be translated to two properties, Name=name and Value=value
    private class func createNameValuePair(pair: String) -> [String] {
        if pair.caseInsensitiveCompare(HTTPCookiePropertyKey.secure.rawValue) == .orderedSame {
            return ["Secure=TRUE"]
        }
        let name = pair.components(separatedBy: "=")[0]
        let value = pair.components(separatedBy: "\(name)=")[1]
        if !isCookieAttribute(name) {
            return ["Name=\(name)", "Value=\(value)"]
        }
        return [pair]
    }

    /// Returns a dictionary representation of the receiver.
    ///
    /// This method returns a dictionary representation of the
    /// `HTTPCookie` which can be saved and passed to
    /// `init(properties:)` later to reconstitute an equivalent cookie.
    ///
    /// See the `HTTPCookie` `init(properties:)` method for
    /// more information on the constraints imposed on the dictionary, and
    /// for descriptions of the supported keys and values.
    ///
    /// - Experiment: This is a draft API currently under consideration for official import into Foundation as a suitable alternative
    /// - Note: Since this API is under consideration it may be either removed or revised in the near future
    open var properties: [HTTPCookiePropertyKey : Any]? {
        return _properties
    }

    /// The version of the receiver.
    ///
    /// Version 0 maps to "old-style" Netscape cookies.
    /// Version 1 maps to RFC2965 cookies. There may be future versions.
    open var version: Int {
        return _version
    }

    /// The name of the receiver.
    open var name: String {
        return _name
    }

    /// The value of the receiver.
    open var value: String {
        return _value
    }

    /// Returns The expires date of the receiver.
    ///
    /// The expires date is the date when the cookie should be
    /// deleted. The result will be nil if there is no specific expires
    /// date. This will be the case only for *session-only* cookies.
    /*@NSCopying*/ open var expiresDate: Date? {
        return _expiresDate
    }

    /// Whether the receiver is session-only.
    ///
    /// `true` if this receiver should be discarded at the end of the
    /// session (regardless of expiration date), `false` if receiver need not
    /// be discarded at the end of the session.
    open var isSessionOnly: Bool {
        return _sessionOnly
    }

    /// The domain of the receiver.
    ///
    /// This value specifies URL domain to which the cookie
    /// should be sent. A domain with a leading dot means the cookie
    /// should be sent to subdomains as well, assuming certain other
    /// restrictions are valid. See RFC 2965 for more detail.
    open var domain: String {
        return _domain
    }
    
    /// The path of the receiver.
    ///
    /// This value specifies the URL path under the cookie's
    /// domain for which this cookie should be sent. The cookie will also
    /// be sent for children of that path, so `"/"` is the most general.
    open var path: String {
        return _path
    }
   
    /// Whether the receiver should be sent only over secure channels
    ///
    /// Cookies may be marked secure by a server (or by a javascript).
    /// Cookies marked as such must only be sent via an encrypted connection to
    /// trusted servers (i.e. via SSL or TLS), and should not be delievered to any
    /// javascript applications to prevent cross-site scripting vulnerabilities. 
    open var isSecure: Bool {
        return _secure
    }

    /// Whether the receiver should only be sent to HTTP servers per RFC 2965
    ///
    /// Cookies may be marked as HTTPOnly by a server (or by a javascript).
    /// Cookies marked as such must only be sent via HTTP Headers in HTTP Requests
    /// for URL's that match both the path and domain of the respective Cookies.
    /// Specifically these cookies should not be delivered to any javascript
    /// applications to prevent cross-site scripting vulnerabilities.
    open var isHTTPOnly: Bool {
        return _HTTPOnly
    }

    /// The comment of the receiver.
    ///
    /// This value specifies a string which is suitable for
    /// presentation to the user explaining the contents and purpose of this
    /// cookie. It may be nil.
    open var comment: String? {
        return _comment
    }

    /// The comment URL of the receiver.
    ///
    /// This value specifies a URL which is suitable for
    /// presentation to the user as a link for further information about
    /// this cookie. It may be nil.
    /*@NSCopying*/ open var commentURL: URL? {
        return _commentURL
    }

    /// The list ports to which the receiver should be sent.
    ///
    /// This value specifies an NSArray of NSNumbers
    /// (containing integers) which specify the only ports to which this
    /// cookie should be sent.
    ///
    /// The array may be nil, in which case this cookie can be sent to any
    /// port.
    open var portList: [NSNumber]? {
        return _portList
    }

    open override var description: String {
        var str = "<\(type(of: self)) "
        str += "version:\(self._version) name:\"\(self._name)\" value:\"\(self._value)\" expiresDate:"
        if let expires = self._expiresDate {
            str += "\(expires)"
        } else {
            str += "nil"
        }
        str += " sessionOnly:\(self._sessionOnly) domain:\"\(self._domain)\" path:\"\(self._path)\" isSecure:\(self._secure) comment:"
        if let comments = self._comment {
            str += "\(comments)"
        } else {
            str += "nil"
        }
        str += " ports:{ "
        if let ports = self._portList {
            str += "\(NSArray(array: (ports)).componentsJoined(by: ","))"
        } else {
            str += "0"
        }
        str += " }>"
        return str
    }
}

//utils for cookie parsing
fileprivate extension String {
    func trim() -> String {
        return self.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)
    }

    func removeCommas() -> String {
        return self.replacingOccurrences(of: ",", with: "")
    }

    func insertComma(at index:Int) -> String {
        return  String(self.characters.prefix(index)) + ","  + String(self.characters.suffix(self.characters.count-index))
    }
}

